Skip to main content

coreason_runtime_rust/
urn_validator.rs

1// Copyright (c) 2026 CoReason, Inc.
2// All rights reserved.
3
4use futures_util::stream::StreamExt;
5use std::sync::Arc;
6
7/// Dynamic validator listening to NATS registry assertions published by the Rust-based URN Authority
8pub struct UrnValidator {
9    nats_client: Option<async_nats::Client>,
10}
11
12impl UrnValidator {
13    /// Creates a new UrnValidator instance
14    pub fn new() -> Self {
15        Self { nats_client: None }
16    }
17
18    /// Connects asynchronously to the NATS cluster broker
19    pub async fn connect(&mut self, url: &str) -> Result<(), String> {
20        let client = async_nats::connect(url)
21            .await
22            .map_err(|e| format!("NATS connection failed: {}", e))?;
23        self.nats_client = Some(client);
24        println!("[URN-VAL] Connected to NATS broker at: {}", url);
25        Ok(())
26    }
27
28    /// Starts an asynchronous message loop validating signature payloads in the background
29    pub async fn start_validation_loop(&self, subject: &str) -> Result<(), String> {
30        let client = self
31            .nats_client
32            .as_ref()
33            .ok_or_else(|| "NATS client not connected".to_string())?;
34
35        let mut subscriber = client
36            .subscribe(subject.to_string())
37            .await
38            .map_err(|e| format!("NATS subscription failed: {}", e))?;
39
40        println!("[URN-VAL] Listening on NATS subject: {}", subject);
41
42        tokio::spawn(async move {
43            while let Some(message) = subscriber.next().await {
44                let payload = String::from_utf8_lossy(&message.payload);
45                println!(
46                    "[URN-VAL] Received registration payload from URN Authority: {}",
47                    payload
48                );
49                // In production, signature checks map directly to coreason_runtime_rust::license functions.
50            }
51        });
52
53        Ok(())
54    }
55}