Expand description
§TAP Node Implementation
This crate provides a complete node implementation for the Transaction Authorization Protocol (TAP). The TAP Node acts as a central hub for managing multiple TAP agents, routing messages between them, and coordinating the entire transaction lifecycle in a secure and scalable manner.
§Overview
The Transaction Authorization Protocol (TAP) is designed for secure, privacy-preserving financial transactions between parties. A TAP Node serves as the infrastructure layer that:
- Manages multiple TAP agents with different roles and capabilities
- Processes incoming and outgoing TAP messages
- Routes messages to the appropriate agents based on DID addressing
- Handles message validation, transformation, and delivery
- Provides an event system for monitoring and reacting to node activities
- Scales to handle high message throughput with a processing pool
§Architecture
The TAP Node is built with several key components:
- Agent Registry: Maintains a collection of TAP agents by their DIDs
- Message Processors: Process, validate, and transform messages
- Message Routers: Determine the target agent for a message
- Processor Pool: Provides concurrent message processing for scalability
- Event Bus: Broadcasts node events to subscribers
- DID Resolver: Resolves DIDs to DID Documents for message verification
§Usage Example
use std::sync::Arc;
use tap_agent::{AgentConfig, DefaultAgent};
use tap_node::{NodeConfig, TapNode, DefaultAgentExt};
use tap_node::message::processor_pool::ProcessorPoolConfig;
use tokio::time::Duration;
// Test secrets resolver for doctests
#[derive(Debug)]
struct TestSecretsResolver {
secrets: std::collections::HashMap<String, didcomm::secrets::Secret>
}
impl TestSecretsResolver {
pub fn new() -> Self {
Self {
secrets: std::collections::HashMap::new()
}
}
}
impl tap_agent::crypto::DebugSecretsResolver for TestSecretsResolver {
fn get_secrets_map(&self) -> &std::collections::HashMap<String, didcomm::secrets::Secret> {
&self.secrets
}
}
async fn example() -> Result<(), Box<dyn std::error::Error>> {
// Create a node with default configuration
let config = NodeConfig::default();
let mut node = TapNode::new(config);
// Configure and start the processor pool
let pool_config = ProcessorPoolConfig {
workers: 4,
channel_capacity: 100,
worker_timeout: Duration::from_secs(30),
};
node.start(pool_config).await?;
// Create and register a TAP agent
// (simplified - in practice you would need to set up proper crypto)
let agent_config = AgentConfig::new("did:example:123".to_string());
// In a real scenario, you'd create these properly:
let did_resolver = Arc::new(tap_agent::did::MultiResolver::default());
let secrets_resolver = Arc::new(TestSecretsResolver::new());
let message_packer = Arc::new(tap_agent::crypto::DefaultMessagePacker::new(
did_resolver, secrets_resolver
));
let agent = DefaultAgent::new(agent_config, message_packer);
node.register_agent(Arc::new(agent)).await?;
// The node is now ready to process messages
// You would typically listen for incoming messages and call:
// node.receive_message(message).await?;
Ok(())
}§Thread Safety and Async
The TAP Node is designed to be thread-safe and fully async, making it suitable for
high-throughput environments. The core TapNode structure can be safely cloned and
shared between threads, with all mutable state protected by appropriate synchronization
primitives.
Re-exports§
pub use error::Error;pub use error::Result;pub use message::sender::HttpMessageSender;pub use message::sender::MessageSender;pub use message::sender::NodeMessageSender;pub use message::sender::WebSocketMessageSender;
Modules§
- agent
- Agent management for TAP Node
- error
- Error handling for TAP Node
- event
- Event System for TAP Node
- message
- Message processing and routing for TAP Node
- resolver
- DID resolution for TAP Node
Structs§
- Node
Config - Configuration for a TAP Node
- TapNode
- The TAP Node
Traits§
- Default
Agent Ext - This trait extends the DefaultAgent with methods for serializing and packing DIDComm messages for transmission. It provides functionality for converting in-memory message objects to secure, serialized formats that follow the DIDComm messaging protocol standards.