### Start the Iroh-backed PostgreSQL gateway example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/postgres-compat.md Runs the postgres_iroh_gateway example with the pgwire feature, opening an Iroh-backed GuardianDB document store and serving SQL over it. Options include --addr, --database, and --path. It prints the node's Iroh id; a second instance with different --addr/--path replicates via mDNS/n0 discovery. ```bash cargo run --features pgwire --example postgres_iroh_gateway # options: -- --addr 127.0.0.1:15432 --database app --path ./guardian_pg_data ``` -------------------------------- ### Basic Usage Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/CONNECTION-POOL.md Demonstrates the full lifecycle of creating a pool, starting the monitor, getting a connection, and releasing it. ```rust use guardian_db::ipfs_core_api::backends::connection_pool::*; // Create pool let config = PoolConfig::default(); let pool = OptimizedConnectionPool::new(config); // Start health monitor let monitor_handle = pool.start_health_monitor(); // Get connection let node_id: PeerId = "12D3KooW...".parse()?; let address: Multiaddr = "/ip4/192.168.1.100/tcp/4001".parse()?; let connection_id = pool.get_connection(node_id, address).await?; // Use connection for operations... // Release connection pool.release_connection(node_id, connection_id).await?; ``` -------------------------------- ### Build and run examples Source: https://github.com/wmaslonek/guardian-db/blob/main/packages/guardiandb-postgres-typeorm/README.md Commands to build the gateway binary and run the example CRUD application. ```bash cargo build --features pgwire --bin guardian-pgwire # gateway binary the DataSource spawns npm install npm run example:crud ``` -------------------------------- ### Initialize GuardianDB and perform basic operations Source: https://github.com/wmaslonek/guardian-db/blob/main/README.md Demonstrates how to start a local Iroh node, initialize the database, and perform basic key-value put and get operations. ```rust use guardian_db::guardian::GuardianDB; use guardian_db::guardian::core::NewGuardianDBOptions; use guardian_db::p2p::network::client::IrohClient; #[tokio::main] async fn main() -> Result<(), Box> { // Start a local Iroh node and open a database persisted under ./guardian_data. let client = IrohClient::development().await?; let db = GuardianDB::new(client, Some(NewGuardianDBOptions { directory: Some("./guardian_data".into()), ..Default::default() })).await?; // Open (or create) a key-value store. Writes replicate to peers automatically. let kv = db.key_value("settings", None).await?; kv.put("theme", b"dark".to_vec()).await?; if let Some(v) = kv.get("theme").await? { println!("theme = {}", String::from_utf8_lossy(&v)); } Ok(()) } ``` -------------------------------- ### Start gateway and connect via psql Source: https://github.com/wmaslonek/guardian-db/blob/main/examples/postgres-typeorm/README.md Start the gateway using cargo and connect using a standard PostgreSQL connection string. ```bash cargo run --features pgwire --bin guardian-pgwire # listens on 127.0.0.1:15432 # canonical connection string (sslmode=disable: the gateway has no TLS; # needed by libpq clients like psql — node-postgres/TypeORM work without it) psql 'postgres://guardian:guardian@127.0.0.1:15432/app?sslmode=disable' ``` -------------------------------- ### Basic Setup of NetworkingMetricsCollector Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/NETWORKING-METRICS.md Initializes the collector and starts a periodic task to update computed metrics every 10 seconds. ```rust use guardian_db::ipfs_core_api::backends::networking_metrics::*; // Create collector let collector = NetworkingMetricsCollector::new(); // Start periodic updates tokio::spawn({ let collector = collector.clone(); async move { let mut interval = tokio::time::interval(Duration::from_secs(10)); loop { interval.tick().await; collector.update_computed_metrics(None).await; } } }); ``` -------------------------------- ### new() constructor usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of creating a controller with new(), either empty or with initial permissions. The example imports HashMap and shows inserting permissions for 'write' and 'admin' categories. ```rust use std::collections::HashMap; // Empty controller (with basic categories) let controller = SimpleAccessController::new(None); // Controller with initial permissions let mut permissions = HashMap::new(); permissions.insert("write".to_string(), vec![ "did:key:alice".to_string(), "did:key:bob".to_string(), ]); permissions.insert("admin".to_string(), vec![ "did:key:alice".to_string(), ]); let controller = SimpleAccessController::new(Some(permissions)); ``` -------------------------------- ### Install Troubleshooting Dependencies Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/COVERAGE.md System-level dependency installation commands for troubleshooting installation failures on Linux distributions. ```bash # Ubuntu/Debian sudo apt-get install pkg-config libssl-dev # Fedora/CentOS sudo dnf install pkg-config openssl-devel ``` -------------------------------- ### Gateway startup output Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/supabase-compat.md Example output displayed upon successful gateway startup. ```text SUPABASE_URL : http://127.0.0.1:54321 ANON_KEY : eyJhbGciOiJIUzI1NiIs... SERVICE_ROLE_KEY : eyJhbGciOiJIUzI1NiIs... JWT_SECRET : (save this to reuse the keys) ``` -------------------------------- ### create() usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Example of using the `create()` function to create a simple access controller with write permissions for all users, then printing the resulting manifest CID. ```rust let params = CreateAccessControllerOptions::default() .with_write(vec!["*".to_string()]); let manifest_cid = create( db.clone(), "simple", params, AccessControllerOption::default(), ).await?; println!("Manifest CID: {}", manifest_cid); ``` -------------------------------- ### Get authorized roles example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/IROH_ACCESS_CONTROLLER_IMPLEMENTATION.md Demonstrates retrieving authorized writers and admins. ```rust let writers = controller.get_authorized_by_role("write").await?; println!("Authorized writers: {:?}", writers); let admins = controller.get_authorized_by_role("admin").await?; // Same as writers for IPFS controller ``` -------------------------------- ### Export permissions example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of capturing the current permission state for backup purposes. ```rust let backup = controller.export_permissions().await; // Save to file, database, etc. ``` -------------------------------- ### Initialize IrohAccessController example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/IROH_ACCESS_CONTROLLER_IMPLEMENTATION.md Demonstrates how to initialize the controller with an Iroh client and configuration options. ```rust use guardian_db::{ ipfs_core_api::IrohClient, access_controller::{ ipfs::IrohAccessController, manifest::CreateAccessControllerOptions, }, }; let ipfs = IrohClient::development().await?; let identity_id = "did:key:z6Mkk...".to_string(); let mut params = CreateAccessControllerOptions::default(); params.set_access("write".to_string(), vec![ identity_id.clone(), "did:key:z6Mkj...".to_string(), ]); let controller = IrohAccessController::new( Arc::new(ipfs), identity_id, params, )?; ``` -------------------------------- ### list_capabilities() usage Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example showing how to retrieve and print all available capabilities. ```rust let capabilities = controller.list_capabilities().await; println!("Available capabilities: {:?}", capabilities); // Output: ["read", "write", "admin", "moderator"] ``` -------------------------------- ### Build and run the CRUD example Source: https://github.com/wmaslonek/guardian-db/blob/main/examples/postgres-typeorm/README.md Commands to build the project and execute the CRUD walkthrough script. ```bash cargo build --features pgwire --bin guardian-pgwire # once, from the repo root npm install npm run crud ``` -------------------------------- ### Manifest JSON Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MANIFEST.md An example of a serialized Manifest document in JSON format. ```json { "type": "ipfs", "params": { "skip_manifest": false, "address": "bafyreib...", "type": "ipfs", "name": "my-controller", "access": { "write": ["did:key:z6Mkk...", "*"] } } } ``` -------------------------------- ### Install Coverage Tools Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/COVERAGE.md Commands to install necessary Rust coverage tools and system dependencies on Ubuntu/Debian. ```bash # Using cargo cargo install cargo-tarpaulin cargo install cargo-llvm-cov # On Ubuntu/Debian (for tarpaulin dependencies) sudo apt-get install pkg-config libssl-dev ``` -------------------------------- ### AccessController log output examples Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/GUARDIAN_DB_ACCESS_CONTROLLER.md Example log entries demonstrating DEBUG and WARN levels for database operations. ```text DEBUG access_controller: Key-value store initialized address="my-db/_access" DEBUG GuardianDB::ac: Event emitted successfully action="grant" capability="write" key_id="did:key:..." WARN GuardianDB::ac: Failed to emit update event error="channel closed" ``` -------------------------------- ### from_options() constructor usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of creating a controller with from_options(). It imports CreateAccessControllerOptions, creates empty options, sets a 'write' permission for a key, and constructs the controller. ```rust use guardian_db::access_controller::manifest::CreateAccessControllerOptions; let mut params = CreateAccessControllerOptions::new_empty(); params.set_access("write".to_string(), vec![ "did:key:alice".to_string(), ]); let controller = SimpleAccessController::from_options(params)?; ``` -------------------------------- ### Save example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Demonstrates serializing the manifest object to a JSON file. ```rust let manifest = controller.save().await?; // Could serialize manifest to JSON/CBOR for storage let json = serde_json::to_string(&manifest)?; std::fs::write("permissions.json", json)?; ``` -------------------------------- ### Clean and recompile P2P chat examples Source: https://github.com/wmaslonek/guardian-db/blob/main/examples/P2P_CHAT_README.md Use these commands to clean the project and rebuild the P2P chat demo and TUI examples when encountering compilation errors. ```bash # Clean and recompile cargo clean cargo build --example p2p_chat_demo cargo build --example p2p_chat_tui ``` -------------------------------- ### list_keys() usage Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example showing how to list keys for the 'write' capability. ```rust let write_keys = controller.list_keys("write").await; // Never fails, returns empty vec if capability doesn't exist ``` -------------------------------- ### Example: Load permissions from another store Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/GUARDIAN_DB_ACCESS_CONTROLLER.md Demonstrates loading a database and retrieving authorized writers. ```rust // Load permissions from another store controller.load("my-database").await?; // Now the controller uses permissions persisted in "my-database/_access" let writers = controller.get_authorized_by_role("write").await?; ``` -------------------------------- ### new_simple() constructor usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of creating a controller with new_simple(). The resulting controller has empty 'read', 'write', and 'admin' categories. ```rust let controller = SimpleAccessController::new_simple(); // Has empty "read", "write", "admin" categories ``` -------------------------------- ### estimate_resources function example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/BATCH-PROCESSOR.md Shows how to implement the estimate_resources method, returning a ResourceEstimate for a given OperationType. The example provides values for the Add operation type. ```rust async fn estimate_resources(&self, operation_type: &OperationType) -> ResourceEstimate { match operation_type { OperationType::Add => ResourceEstimate { cpu_usage: 0.3, memory_bytes: 1024 * 1024, // 1MB io_bytes: 1024 * 1024, bandwidth_bytes: 512 * 1024, estimated_time_ms: 50, }, // ... other types } } ``` -------------------------------- ### AccessController load usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Demonstrates how to restore a controller state using a backup CID. ```rust async fn restore_controller( controller: &dyn AccessController, backup_cid: &str, ) -> Result<()> { println!("Restoring from {}", backup_cid); controller.load(backup_cid).await?; println!("Controller restored"); Ok(()) } ``` -------------------------------- ### Import permissions example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Demonstrates backing up, modifying, and restoring permissions. This operation is atomic. ```rust // Backup let backup = controller.export_permissions().await; // Make changes... controller.grant("write", "did:key:eve").await?; // Restore from backup controller.import_permissions(backup).await?; // Eve's permission is now gone ``` -------------------------------- ### Connection Acquisition Usage Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/CONNECTION-POOL.md Example of initializing an OptimizedConnectionPool and acquiring a connection. ```rust let pool = OptimizedConnectionPool::new(PoolConfig::default()); let node_id = "12D3KooW...".parse()?; let address: Multiaddr = "/ip4/192.168.1.100/tcp/4001".parse()?; let connection_id = pool.get_connection(node_id, address).await?; println!("Got connection: {}", connection_id); ``` -------------------------------- ### grant() Usage Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Example granting write to a specific user, admin to another, and universal read access using the "*" wildcard. ```rust async fn setup_permissions(controller: &dyn AccessController) -> Result<()> { // Grant write to specific user controller.grant("write", "did:key:alice").await?; // Grant admin to another user controller.grant("admin", "did:key:bob").await?; // Grant universal read controller.grant("read", "*").await?; Ok(()) } ``` -------------------------------- ### Retrieve Content Usage Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/IROH-BACKEND.md Demonstrates how to read content from the backend into a vector. ```rust let mut reader = backend.cat("bafkreid...").await?; let mut content = Vec::new(); reader.read_to_end(&mut content).await?; ``` -------------------------------- ### AccessController save usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Demonstrates how to backup a controller and extract the manifest address. ```rust async fn backup_controller(controller: &dyn AccessController) -> Result { // Save state let manifest = controller.save().await?; // Extract CID/address let address = manifest.address().to_string(); println!("Backed up to: {}", address); Ok(address) } ``` -------------------------------- ### Connect with node-postgres Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/postgres-compat.md Example of connecting to the gateway using the pg library. ```ts import pg from "pg"; const client = new pg.Client({ connectionString: "postgres://guardian:guardian@127.0.0.1:15432/app?sslmode=disable", }); await client.connect(); const { rows } = await client.query("SELECT count(*) FROM users"); await client.end(); ``` -------------------------------- ### Tune BatchConfig for Workloads Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/BATCH-PROCESSOR.md Provides configuration examples for write-heavy and read-heavy workloads. ```rust // For write-heavy workload (many Adds) let config = BatchConfig { max_batch_size: 150, max_batch_wait_ms: 75, ..Default::default() }; // For read-heavy workload (many Gets) let config = BatchConfig { max_batch_size: 100, max_batch_wait_ms: 25, // Process Gets faster ..Default::default() }; ``` -------------------------------- ### Create and Configure Controller Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/IROH_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of initializing an IrohClient, setting up initial permissions, and creating an IrohAccessController instance. ```APIDOC ## Create and Configure Controller ### Description Initializes an IPFS client, sets up initial permissions, and creates an IrohAccessController. ### Code Example ```rust use guardian_db::{ ipfs_core_api::IrohClient, access_controller::{ ipfs::IrohAccessController, manifest::CreateAccessControllerOptions, }, }; use std::sync::Arc; // Initialize IPFS client let ipfs = Arc::new(IrohClient::development().await?); // Setup initial permissions let identity_id = "did:key:z6MkkSample123".to_string(); let mut params = CreateAccessControllerOptions::default(); params.set_access("write".to_string(), vec![ identity_id.clone(), "did:key:z6MkkOtherUser".to_string(), ]); // Create controller let controller = IrohAccessController::new( ipfs.clone(), identity_id, params, )?; println!("Controller type: {}", controller.get_type()); ``` ``` -------------------------------- ### Connection Reuse Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/CONNECTION-POOL.md Shows how the pool reuses connections when the same peer is accessed multiple times. ```rust let node_id: PeerId = "12D3KooW...".parse()?; let address: Multiaddr = "/ip4/192.168.1.100/tcp/4001".parse()?; // First connection let conn1 = pool.get_connection(node_id, address.clone()).await?; println!("First connection: {}", conn1); pool.release_connection(node_id, conn1).await?; // Second connection (reuses first) let conn2 = pool.get_connection(node_id, address.clone()).await?; println!("Second connection: {}", conn2); // Check stats let stats = pool.get_stats().await; assert_eq!(stats.connections_created, 1); assert_eq!(stats.connections_reused, 1); ``` -------------------------------- ### Starting Auto-Processor Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/BATCH-PROCESSOR.md Starts a background task that automatically processes batches. ```rust pub fn start_auto_processor(&self) -> tokio::task::JoinHandle<()> ``` ```rust let processor = BatchProcessor::new(config); let handle = processor.start_auto_processor(); // Processor now runs in background // Add operations and they'll be batched automatically ``` -------------------------------- ### Run the demo Source: https://github.com/wmaslonek/guardian-db/blob/main/examples/postgres-typeorm/README.md Commands to build the gateway and execute the self-contained demo script. ```bash # 1. Build the gateway (from the repo root) cargo build --features pgwire --bin guardian-pgwire # 2. Run the self-contained demo (spawns the gateway, migrates, seeds, queries) cd examples/postgres-typeorm npm install npm run demo ``` -------------------------------- ### Initialize and Configure Iroh Client Source: https://github.com/wmaslonek/guardian-db/blob/main/README.md Demonstrates both a quick development setup and an advanced configuration for the Iroh client, including pubsub, discovery, and storage settings. ```rust use guardian_db::p2p::network::client::IrohClient; use guardian_db::p2p::network::config::ClientConfig; use tokio::io::AsyncReadExt; #[tokio::main] async fn main() -> Result<(), Box> { // Quick development setup (Native Iroh with QUIC transport) let client = IrohClient::development().await?; println!("✓ Iroh Client initialized with native QUIC backend"); // Advanced configuration with native Iroh let config = ClientConfig { enable_pubsub: true, // iroh-gossip support data_store_path: Some("./iroh_data".into()), port: 4001, // Iroh endpoint port (0 = random) enable_discovery_n0: true, // Discovery via n0.computer (Pkarr/DNS) enable_discovery_mdns: true, // Local mDNS discovery known_peers: vec![], // NodeIds of known peers network: Default::default(), // Network tuning (timeout, buffer, etc.) storage: Default::default(), // iroh-blobs storage config gossip: Default::default(), // iroh-gossip config }; let client = IrohClient::new(config).await?; println!("✓ Advanced Iroh Client configured"); // Add data using native Iroh backend (BLAKE3 hashing) let data = "Hello from GuardianDB! This is stored with Iroh."; let add_response = client.add_bytes(data.as_bytes().to_vec()).await?; println!("Added to Iroh: {}", add_response.hash); println!("Size: {} bytes", add_response.size); // Retrieve data from Iroh (with smart caching) let mut stream = client.backend().cat(&add_response.hash).await?; let mut buffer = Vec::new(); stream.read_to_end(&mut buffer).await?; let retrieved_text = String::from_utf8(buffer)?; println!("Retrieved: {}", retrieved_text); // Pin the content (persistent tags prevent GC) client.backend().pin_add(&add_response.hash).await?; println!("Content pinned with persistent tag"); // Get node info (Iroh NodeId) let node_info = client.id().await?; println!("Node ID: {}", node_info.id); println!("Protocol Version: {}", node_info.protocol_version); println!("Agent Version: {}", node_info.agent_version); Ok(()) } ``` -------------------------------- ### Access Controller Log Examples Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/IROH_ACCESS_CONTROLLER_IMPLEMENTATION.md Sample DEBUG logs generated by the ipfs_access_controller target. ```text DEBUG ipfs_access_controller: Permission granted successfully capability="write" key_id="did:key:z6Mkk..." total_keys=3 DEBUG ipfs_access_controller: Permission already exists capability="write" key_id="did:key:z6Mkk..." DEBUG ipfs_access_controller: Permission revoked successfully capability="write" key_id="did:key:z6Mkj..." remaining_keys=2 DEBUG ipfs_access_controller: IPFS access controller saved cid="bafyreib..." DEBUG ipfs_access_controller: Closing IPFS access controller write_access_count=2 ``` -------------------------------- ### Run connection string demo Source: https://github.com/wmaslonek/guardian-db/blob/main/examples/postgres-typeorm/README.md Execute the end-to-end connection string demonstration. ```bash npm run connection-string ``` -------------------------------- ### Check Rust installation Source: https://github.com/wmaslonek/guardian-db/blob/main/examples/P2P_CHAT_README.md Verify that Rust and Cargo are installed on your system before running the project. ```bash rustc --version cargo --version ``` -------------------------------- ### Basic BatchProcessor Usage Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/BATCH-PROCESSOR.md Initialize the processor with default settings, start the auto-processor, and add a single operation. ```rust use guardian_db::ipfs_core_api::backends::batch_processor::*; // Create processor with default config let processor = BatchProcessor::new(BatchConfig::default()); // Start auto-processor let handle = processor.start_auto_processor(); // Add operations let data = Bytes::from("Hello, Batch!"); let result = processor.add_operation( OperationType::Add, OperationData::AddData { data, options: AddOptions::default(), }, 5, // Normal priority ).await?; // Handle result match result { OperationResult::AddResult(response) => { println!("Added: {}", response.hash); }, _ => unreachable!(), } ``` -------------------------------- ### Connect using plain clients Source: https://github.com/wmaslonek/guardian-db/blob/main/packages/guardiandb-postgres-typeorm/README.md Examples of connecting to an already-running gateway using node-postgres or plain TypeORM. ```ts // node-postgres const client = new pg.Client({ connectionString: "postgres://guardian:guardian@127.0.0.1:15432/app?sslmode=disable" }); // plain TypeORM const ds = new DataSource({ type: "postgres", url: "postgres://guardian:guardian@127.0.0.1:15432/app", ssl: false, entities: [...] }); ``` -------------------------------- ### Start Health Monitor Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/CONNECTION-POOL.md Starts a background task for health monitoring and returns a JoinHandle. ```rust pub fn start_health_monitor(&self) -> tokio::task::JoinHandle<()> ``` -------------------------------- ### GET /graphql/v1?query=... Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/supabase-compat.md Supports GraphiQL interface. Mutations over GET are rejected. ```APIDOC ## GET /graphql/v1?query=... ### Description Provides a GraphiQL interface. Only queries are allowed; mutations are rejected over GET. ### Method GET ### Endpoint /graphql/v1?query=... ### Parameters #### Query Parameters - **query** (string) - Required - The GraphQL query string. ### Response #### Success Response (200) Returns the GraphQL response in the same format as POST. ### Error Handling Mutations over GET are rejected. ``` -------------------------------- ### Initialize and Use Iroh Pub/Sub Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/IROH-PUBSUB.md Demonstrates how to initialize the Iroh backend, create a pubsub interface, subscribe to a topic, publish messages, and list active peers. ```rust use guardian_db::ipfs_core_api::backends::IrohBackend; use std::sync::Arc; // Initialize backend let iroh_backend = Arc::new(IrohBackend::new(&config).await?); // Create pubsub interface let mut pubsub = iroh_backend.create_pubsub_interface(); // Subscribe to topic let topic = pubsub.topic_subscribe("chat").await?; println!("Subscribed to topic: {}", topic.topic()); // Publish messages topic.publish(b"Hello, world!".to_vec()).await?; topic.publish(b"This is a test message".to_vec()).await?; // List peers on topic let peers = topic.peers().await?; println!("Topic has {} subscribers", peers.len()); for peer in peers { println!(" - {}", peer); } ``` -------------------------------- ### Build and test project Source: https://github.com/wmaslonek/guardian-db/blob/main/packages/guardiandb-postgres-typeorm/README.md Commands to build the gateway binary and run the project tests. ```bash cargo build --features pgwire --bin guardian-pgwire # gateway binary the package spawns npm install npm test ``` -------------------------------- ### add_entry_safe usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Example showing how to use can_append to validate an entry before adding it to the log. ```rust async fn add_entry_safe( log: &mut Log, controller: &dyn AccessController, entry: Entry, identity_provider: &dyn IdentityProvider, context: &dyn CanAppendAdditionalContext, ) -> Result<()> { // Validate first controller.can_append(&entry, identity_provider, context).await?; // Only add if authorized log.append(entry).await?; Ok(()) } ``` -------------------------------- ### Initialize GuardianDB with custom ClientConfig Source: https://github.com/wmaslonek/guardian-db/blob/main/README.md Demonstrates how to manually construct a ClientConfig with specific networking, storage, and gossip settings, then use it to initialize a GuardianDB instance. ```rust use guardian_db::guardian::GuardianDB; use guardian_db::guardian::core::NewGuardianDBOptions; use guardian_db::p2p::network::client::IrohClient; use guardian_db::p2p::network::config::{ClientConfig, NetworkConfig, StorageConfig, GossipConfig}; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), Box> { let config = ClientConfig { enable_pubsub: true, // iroh-gossip data_store_path: Some("./iroh_data".into()), port: 4001, // 0 = random port enable_discovery_n0: true, // global discovery (Pkarr/DNS) enable_discovery_mdns: true, // local discovery known_peers: vec![], // bootstrap NodeIds network: NetworkConfig { connection_timeout: Duration::from_secs(60), max_peers_per_session: 1000, io_buffer_size: 128 * 1024, keepalive_interval: Duration::from_secs(120), }, storage: StorageConfig { enable_memory_cache: true, max_cache_size: 1024 * 1024 * 1024, // 1 GB max_blob_size: 100 * 1024 * 1024, // 100 MB per blob enable_gc: true, gc_interval: Duration::from_secs(1800), }, gossip: GossipConfig { max_message_size: 10 * 1024 * 1024, message_buffer_size: 10000, operation_timeout: Duration::from_secs(60), heartbeat_interval: Duration::from_millis(500), max_topics: 1000, }, }; let client = IrohClient::new(config).await?; let db = GuardianDB::new(client, Some(NewGuardianDBOptions { directory: Some("./guardian_data".into()), ..Default::default() })).await?; let _ = db; // open stores via db.log() / db.key_value() / db.docs() Ok(()) } ``` -------------------------------- ### list_available_types() usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Example of using the `list_available_types()` function to print the available controller types. ```rust let types = list_available_types(); println!("Available controllers: {:?}", types); // Output: Available controllers: ["simple", "guardian", "ipfs"] ``` -------------------------------- ### HTTP GET Implementation Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/IROH-BACKEND.md Performs a manual HTTP/1.1 GET request over a raw TCP stream. ```rust async fn perform_bootstrap_http_get(api_url: &str) -> Result { // Parse URL let parsed_url = parse_http_url(api_url)?; // Connect via TCP let stream = tokio::net::TcpStream::connect(&parsed_url.socket_addr).await?; let mut stream = tokio::io::BufWriter::new(stream); // Construct HTTP/1.1 GET request let http_request = format!( "GET {} HTTP/1.1\r\n\ Host: {}\r\n\ User-Agent: iroh-discovery/0.92.0\r\n\ Accept: application/json, text/plain\r\n\ Connection: close\r\n\ Cache-Control: no-cache\r\n\ \r\n", parsed_url.path, parsed_url.host ); // Send request stream.write_all(http_request.as_bytes()).await?; stream.flush().await?; // Read response let mut response_buffer = Vec::new(); stream.read_to_end(&mut response_buffer).await?; // Parse HTTP response let response_text = String::from_utf8(response_buffer)?; parse_http_response(&response_text) } ``` -------------------------------- ### Initialize KeySynchronizer Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/KEY-SYNCHRONIZER.md Demonstrates how to configure and initialize the KeySynchronizer using ClientConfig. ```rust use guardian_db::ipfs_core_api::backends::key_synchronizer::*; use guardian_db::ipfs_core_api::config::ClientConfig; // Create configuration let config = ClientConfig { data_store_path: Some(PathBuf::from("/data/guardian")), ..Default::default() }; // Initialize synchronizer let synchronizer = KeySynchronizer::new(&config).await?; println!("PeerID: {}", synchronizer.node_id()); ``` -------------------------------- ### Using the Cache Interface Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/cache/CACHE.md Shows how to instantiate a cache at a specific path, perform basic put/get operations, and trigger cleanup. ```rust use guardian_db::cache::Cache; // Create cache instance let (datastore, cleanup) = Cache::new("/path/to/cache", None)?; // Use the datastore datastore.put(b"key", b"value").await?; let value = datastore.get(b"key").await?; // Cleanup when done cleanup()?; ``` -------------------------------- ### is_supported_type() usage examples Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Examples of the `is_supported_type()` function checking various controller types, including case-insensitive checks. ```rust assert!(is_supported_type("simple")); assert!(is_supported_type("SIMPLE")); // case-insensitive assert!(is_supported_type("guardian")); assert!(is_supported_type("ipfs")); assert!(!is_supported_type("unknown")); ``` -------------------------------- ### Clone and Build Guardian-DB Source: https://github.com/wmaslonek/guardian-db/blob/main/README.md Initial steps to clone the repository, build the library, run tests, and execute the P2P chat demo. ```bash git clone https://github.com/wmaslonek/guardian-db.git cd guardian-db cargo build # build the library cargo test # run the test suite cargo run --example p2p_chat_tui # try a P2P demo (see examples/) ``` -------------------------------- ### resolve() usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Example of using the `resolve()` function to load an access controller and check write permissions for an entry. ```rust let controller = resolve( db.clone(), "my-database", ¶ms, AccessControllerOption::default(), ).await?; // Check permissions let can_write = controller.can_append(&entry, &identity_provider).await?; ``` -------------------------------- ### Add Content Usage Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/IROH-BACKEND.md Demonstrates how to add data to the backend using a cursor and print the resulting CID. ```rust let data = Box::pin(std::io::Cursor::new(b"Hello IPFS")); let response = backend.add(data).await?; println!("CID: {}", response.hash); ``` -------------------------------- ### get_authorized_by_role() Usage Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Example listing authorized writers for the "write" role. Uses the ? operator to propagate errors. ```rust async fn list_writers(controller: &dyn AccessController) -> Result<()> { let writers = controller.get_authorized_by_role("write").await?; println!("Authorized writers:"); for writer in writers { println!(" - {}", writer); } Ok(()) } ``` -------------------------------- ### Example Logs for SimpleAccessController Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Sample output showing INFO, DEBUG, and WARN log levels for various access control operations. ```text INFO simple_access_controller: Created SimpleAccessController categories=["read", "write", "admin"] total_permissions=0 INFO simple_access_controller: Granting permission: capability="write", key_id="did:key:alice" DEBUG simple_access_controller: Permission granted successfully: capability="write" key_id="did:key:alice" total_keys=1 DEBUG simple_access_controller: Checking append permission: entry_id="did:key:alice" DEBUG simple_access_controller: Append permission granted (write key): entry_id="did:key:alice" WARN simple_access_controller: Access denied for append operation: entry_id="did:key:eve" available_write_keys=["did:key:alice"] ``` -------------------------------- ### get_type() Usage Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Example showing how to print the controller type. Output for a SimpleAccessController is "Controller type: simple". ```rust fn print_controller_type(controller: &dyn AccessController) { println!("Controller type: {}", controller.get_type()); } let simple = SimpleAccessController::new_simple(); print_controller_type(&simple); // Output: Controller type: simple ``` -------------------------------- ### Trusted Peer Management Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/KEY-SYNCHRONIZER.md Shows how to add a trusted peer with a verified public key, and warns against trusting unknown peers with unverified keys. ```rust // ✓ Good: Verified public key let verified_pubkey = exchange_keys_securely(node_id).await?; synchronizer.add_trusted_peer(node_id, verified_pubkey).await?; // ✗ Bad: Trusting unknown peer synchronizer.add_trusted_peer(unknown_peer, unverified_key).await?; ``` -------------------------------- ### Wire Protocol JSON Message Examples Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/SENTINEL_TUI.md Examples of request, single reply, and stream messages using the newline-delimited JSON format. ```jsonc // → request { "id": 7, "op": "stores.list" } { "id": 8, "op": "acl.grant", "args": { "controller": "…", "role": "write", "key_id": "…" } } { "id": 9, "op": "events.subscribe", "args": { "kinds": ["sync", "peer"] } } // ← single reply { "id": 7, "ok": true, "data": { "stores": [ … ] } } { "id": 8, "ok": false, "error": { "code": "acl_denied", "message": "…" } } // ← stream (multiple messages with the same id, until "end") { "id": 9, "event": { "kind": "sync", "peer": "abcd…", "ts": "…" } } { "id": 9, "end": true } ``` -------------------------------- ### Process Get Batch in Parallel Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/BATCH-PROCESSOR.md Processes get batch operations in parallel using tokio tasks to optimize for network-bound tasks. ```rust async fn process_get_batch_static(batch: Vec) -> Result<()> { // Spawn parallel tasks let futures = batch.into_iter().map(|operation| { tokio::spawn(async move { Self::process_individual_operation_static(operation).await }) }); // Wait for all let results = futures::future::join_all(futures).await; // Handle errors for result in results { if let Err(e) = result { debug!("Get operation error: {}", e); } } Ok(()) } ``` -------------------------------- ### Create and Configure IrohAccessController Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/IROH_ACCESS_CONTROLLER_IMPLEMENTATION.md Initialize the IPFS client and configure initial permissions before creating the controller instance. ```rust use guardian_db::{ ipfs_core_api::IrohClient, access_controller::{ ipfs::IrohAccessController, manifest::CreateAccessControllerOptions, }, }; use std::sync::Arc; // Initialize IPFS client let ipfs = Arc::new(IrohClient::development().await?); // Setup initial permissions let identity_id = "did:key:z6MkkSample123".to_string(); let mut params = CreateAccessControllerOptions::default(); params.set_access("write".to_string(), vec![ identity_id.clone(), "did:key:z6MkkOtherUser".to_string(), ]); // Create controller let controller = IrohAccessController::new( ipfs.clone(), identity_id, params, )?; println!("Controller type: {}", controller.get_type()); ``` -------------------------------- ### Initialize IrohBackend Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/iroh/backends/IROH-BACKEND.md Configure and initialize the Iroh backend using ClientConfig. ```rust use guardian_db::ipfs_core_api::backends::IrohBackend; use guardian_db::ipfs_core_api::config::ClientConfig; // Create configuration let config = ClientConfig { data_store_path: Some(PathBuf::from("/data/iroh")), max_peers_per_session: 50, cache_size_mb: 512, ..Default::default() }; // Initialize backend let backend = IrohBackend::new(config).await?; ``` -------------------------------- ### revoke() Usage Example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_TRAITS.md Example removing all permissions (write, admin, read) for a user. Revoking non-existent permissions is a no-op returning Ok. ```rust async fn remove_user_access( controller: &dyn AccessController, user_id: &str, ) -> Result<()> { // Remove all permissions for user controller.revoke("write", user_id).await?; controller.revoke("admin", user_id).await?; controller.revoke("read", user_id).await?; println!("All permissions revoked for {}", user_id); Ok(()) } ``` -------------------------------- ### Rust documentation comment example Source: https://github.com/wmaslonek/guardian-db/blob/main/CONTRIBUTING.md Use this documentation comment format for public functions. It includes sections for arguments, returns, examples, and errors. ```rust /// Creates a new instance of EventLogStore. /// /// # Arguments /// /// * `name` - Unique name for the store /// * `options` - Configuration options /// /// # Returns /// /// Returns `Result` /// /// # Examples /// /// ```rust /// use guardian_db::EventLogStore; /// /// let store = EventLogStore::new("my-log", None)?; /// ``` /// /// # Errors /// /// Returns error if: /// - Name already exists /// - Invalid configuration pub fn new(name: &str, options: Option) -> Result { // implementation } ``` -------------------------------- ### Create access controller with custom permissions Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Demonstrates how to define custom permissions using a HashMap and initialize an access controller with CreateAccessControllerOptions. ```rust use std::collections::HashMap; let mut permissions = HashMap::new(); permissions.insert("write".to_string(), vec![ "did:key:z6Mkk...".to_string(), "did:key:z6Mkj...".to_string(), ]); permissions.insert("admin".to_string(), vec![ "did:key:z6Mkk...".to_string(), ]); let params = CreateAccessControllerOptions::new() .with_access(permissions); let cid = create(db.clone(), "simple", params, None).await?; ``` -------------------------------- ### revoke_multiple() method usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of bulk revoking permissions with revoke_multiple(). Shows revoking a 'write' capability from two keys in a single call. ```rust controller.revoke_multiple("write", vec![ "did:key:alice", "did:key:bob", ]).await?; ``` -------------------------------- ### Complete Manifest Lifecycle with IrohClient and create_manifest_with_validation Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MANIFEST.md Shows the full workflow: initialize IPFS with IrohClient::development(), create an access controller configuration, validate it locally with create_manifest_with_validation, store it in IPFS with create(), and load it back with resolve(). The example uses type 'ipfs' and grants write access to two DIDs. ```rust use guardian_db::{ ipfs_core_api::IrohClient, access_controller::manifest::*, }; use std::sync::Arc; // 1. Initialize IPFS let ipfs = Arc::new(IrohClient::development().await?); // 2. Create configuration let mut params = CreateAccessControllerOptions::new_empty(); params.set_type("ipfs".to_string()); params.set_name("auth-controller".to_string()); params.set_access("write".to_string(), vec![ "did:key:alice".to_string(), "did:key:bob".to_string(), ]); // 3. Validate locally let manifest = create_manifest_with_validation( "ipfs".to_string(), params.clone(), )?; println!("Manifest valid: {}", manifest.get_type); // 4. Store in IPFS let cid = create( ipfs.clone(), "ipfs".to_string(), ¶ms, ).await?; println!("Manifest CID: {}", cid); // 5. Load from IPFS let loaded = resolve( ipfs.clone(), &cid.to_string(), &CreateAccessControllerOptions::new_empty(), ).await?; // 6. Verify loaded data assert_eq!(loaded.get_type, "ipfs"); assert_eq!(loaded.params.get_name(), "auth-controller"); ``` -------------------------------- ### Creating a Cache Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/cache/CACHE.md Demonstrates initializing a default persistent cache, a custom cache with specific options, and an in-memory cache for testing. ```rust use guardian_db::cache::{create_default_cache, Options, CacheMode}; // Default cache (persistent, 100MB) let cache = create_default_cache(); // Custom cache with options let cache = create_cache(Options { span: Some(tracing::info_span!("my_cache")), max_cache_size: Some(500 * 1024 * 1024), // 500MB cache_mode: CacheMode::Persistent, }); // In-memory cache for testing let cache = create_memory_cache(); ``` -------------------------------- ### ensure_address() usage examples Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Examples of the `ensure_address()` function normalizing various address inputs, including adding the `/_access` suffix and handling empty strings. ```rust assert_eq!(ensure_address("my-database"), "my-database/_access"); assert_eq!(ensure_address("my-database/"), "my-database/_access"); assert_eq!(ensure_address("my-database/_access"), "my-database/_access"); assert_eq!(ensure_address(""), "_access"); ``` -------------------------------- ### Creating a LevelDown Cache Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/cache/LEVEL_DOWN_CACHE.md Demonstrates initializing a LevelDownCache with either default or custom options. ```rust use guardian_db::cache::level_down::LevelDownCache; use guardian_db::cache::cache::Options; // Create with default options let cache = LevelDownCache::new(None); // Create with custom options let opts = Options { span: Some(tracing::info_span!("my_cache")), max_cache_size: Some(200 * 1024 * 1024), // 200MB ..Default::default() }; let cache = LevelDownCache::new(Some(&opts)); ``` -------------------------------- ### revoke() method usage example Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/SIMPLE_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of revoking permissions with revoke(). Shows revoking a 'write' permission and revoking from a non-existent capability, which is a no-op and returns OK. ```rust // Revoke write permission controller.revoke("write", "did:key:alice").await?; // Revoke from non-existent capability (no-op, no error) controller.revoke("nonexistent", "did:key:bob").await?; // OK ``` -------------------------------- ### Load and Verify Permissions Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/IROH_ACCESS_CONTROLLER_IMPLEMENTATION.md Example of creating a new controller instance and loading permissions from a saved CID. ```APIDOC ## Load and Verify Permissions ### Description Shows how to create a new controller and load permissions from an IPFS CID. ### Code Example ```rust // Create new controller instance let controller2 = IrohAccessController::new( ipfs.clone(), "temporary".to_string(), CreateAccessControllerOptions::default(), )?; // Load permissions from CID let saved_cid = "bafyreib..."; controller2.load(saved_cid).await?; // Verify loaded permissions let writers = controller2.get_authorized_by_role("write").await?; println!("Loaded {} writers", writers.len()); for writer in writers { println!(" - {}", writer); } ``` ``` -------------------------------- ### validate_address() usage examples Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/ACCESS_CONTROLLER_MOD.md Examples of the `validate_address()` function validating addresses, including valid addresses and those that trigger errors for being empty, containing path traversal, or being too long. ```rust validate_address("my-database")?; // OK validate_address("")?; // Error: Address cannot be empty validate_address("foo/../bar")?; // Error: Invalid path components validate_address("a".repeat(1001).as_str())?; // Error: Address too long ``` -------------------------------- ### Example: Close the controller Source: https://github.com/wmaslonek/guardian-db/blob/main/docs/access_controller/GUARDIAN_DB_ACCESS_CONTROLLER.md Demonstrates closing the controller after use. ```rust // Close the controller at the end of use controller.close().await?; ```