ai_agent_bitcoin_escrow/lib.rs
1//! # AI Agent Bitcoin Escrow Library
2//!
3//! A Rust library that enables AI agents to create, manage, and execute Bitcoin
4//! escrow contracts using multisig. The library supports condition-based fund
5//! releases triggered by AI agent decisions or external oracles, with full
6//! audit logging for all actions.
7//!
8//! ## Features
9//!
10//! - **Multisig Support**: 2-of-3 (or n-of-m) multisig escrow contracts
11//! - **Condition-Based Release**: AI decisions, oracle triggers, timelocks
12//! - **Audit Logging**: Immutable, chained audit log for all operations
13//! - **Oracle Integration**: HTTP-based oracle support for real-world data
14//! - **AI Agent Autonomy**: Designed for autonomous AI agent economic activities
15//!
16//! ## Quick Start
17//!
18//! ```rust,no_run
19//! use ai_agent_bitcoin_escrow::{
20//! escrow::{EscrowBuilder, EscrowManager},
21//! multisig::create_participant,
22//! conditions::ConditionBuilder,
23//! audit::AuditLogger,
24//! types::{EscrowConfig, EscrowRole},
25//! };
26//! use bitcoin::Network;
27//!
28//! // Create an escrow manager with audit logging
29//! let audit = AuditLogger::new("/tmp/audit.log").unwrap();
30//! let mut manager = EscrowManager::new(audit);
31//!
32//! // Create participants
33//! let (buyer, _buyer_key) = create_participant(
34//! EscrowRole::Buyer,
35//! "buyer-1".to_string(),
36//! Network::Testnet
37//! ).unwrap();
38//! let (seller, _seller_key) = create_participant(
39//! EscrowRole::Seller,
40//! "seller-1".to_string(),
41//! Network::Testnet
42//! ).unwrap();
43//! let (arbiter, _arbiter_key) = create_participant(
44//! EscrowRole::Arbiter,
45//! "arbiter-1".to_string(),
46//! Network::Testnet
47//! ).unwrap();
48//!
49//! // Build an escrow contract
50//! let contract = EscrowBuilder::new()
51//! .network(Network::Testnet)
52//! .threshold(2)
53//! .participant(buyer)
54//! .participant(seller)
55//! .participant(arbiter)
56//! .description("AI agent bounty payment")
57//! .build()
58//! .unwrap();
59//!
60//! println!("Escrow contract created: {}", contract.id);
61//! ```
62//!
63//! ## Architecture
64//!
65//! The library is organized into several modules:
66//!
67//! - [`escrow`] - Main escrow contract management
68//! - [`multisig`] - Multisignature wallet operations
69//! - [`conditions`] - Release condition evaluation
70//! - [`audit`] - Immutable audit logging
71//! - [`oracle`] - External oracle integration
72//! - [`types`] - Common types and structures
73//! - [`error`] - Error handling
74//!
75//! ## AI Agent Integration
76//!
77//! This library is designed to be used by AI agents for autonomous economic
78//! activities. Key features for AI agent autonomy:
79//!
80//! - **Self-Custody**: AI agents control their own keys
81//! - **Verifiable Actions**: All operations are logged in an immutable audit log
82//! - **Conditional Releases**: Funds can be released based on AI decisions
83//! - **Oracle Integration**: Real-world data can trigger releases
84//!
85//! ## Security Considerations
86//!
87//! - All private keys should be securely stored
88//! - The audit log provides a verifiable record of all actions
89//! - Multisig ensures no single party can unilaterally control funds
90//! - Timelocks provide a safety mechanism for dispute resolution
91//!
92//! ## License
93//!
94//! Dual-licensed under MIT or Apache-2.0.
95
96pub mod audit;
97pub mod conditions;
98pub mod error;
99pub mod escrow;
100pub mod multisig;
101pub mod oracle;
102pub mod types;
103
104// Re-export commonly used types at the crate root
105pub use error::{EscrowError, Result};
106pub use escrow::{EscrowBuilder, EscrowContract, EscrowManager};
107pub use types::{
108 AgentId, ConditionResult, EscrowConfig, EscrowId, EscrowParticipant,
109 EscrowRole, EscrowStatus, OracleId, ReleaseCondition,
110};
111
112/// Library version.
113pub const VERSION: &str = env!("CARGO_PKG_VERSION");
114
115/// Library name.
116pub const NAME: &str = env!("CARGO_PKG_NAME");
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use audit::AuditLogger;
122 use bitcoin::Network;
123 use escrow::EscrowBuilder;
124 use multisig::create_participant;
125 use types::EscrowRole;
126
127 #[test]
128 fn test_library_version() {
129 assert!(!VERSION.is_empty());
130 assert_eq!(NAME, "ai-agent-bitcoin-escrow");
131 }
132
133 #[test]
134 fn test_full_escrow_workflow() {
135 // Create participants
136 let (buyer, _) = create_participant(EscrowRole::Buyer, "buyer-1".to_string(), Network::Testnet).unwrap();
137 let (seller, _) = create_participant(EscrowRole::Seller, "seller-1".to_string(), Network::Testnet).unwrap();
138 let (arbiter, _) = create_participant(EscrowRole::Arbiter, "arbiter-1".to_string(), Network::Testnet).unwrap();
139
140 // Build escrow
141 let contract = EscrowBuilder::new()
142 .network(Network::Testnet)
143 .threshold(2)
144 .participant(buyer)
145 .participant(seller)
146 .participant(arbiter)
147 .description("Test bounty payment")
148 .build()
149 .unwrap();
150
151 // Verify contract
152 assert_eq!(contract.status, EscrowStatus::Created);
153 assert_eq!(contract.participants.len(), 3);
154 assert_eq!(contract.config.threshold, 2);
155
156 // Initialize multisig
157 let mut contract = contract;
158 contract.initialize_multisig().unwrap();
159 assert!(contract.multisig.is_some());
160
161 // Get escrow address
162 let address = contract.escrow_address().unwrap();
163 assert!(!address.to_string().is_empty());
164 }
165
166 #[tokio::test]
167 async fn test_escrow_manager_workflow() {
168 let audit = AuditLogger::in_memory();
169 let mut manager = EscrowManager::new(audit);
170
171 // Create contract
172 let contract = manager
173 .create_contract(
174 EscrowConfig::default(),
175 Some("Test escrow".to_string()),
176 "test-agent".to_string(),
177 )
178 .unwrap();
179
180 let contract_id = contract.id.clone();
181
182 // Add participants
183 let (buyer, _) = create_participant(EscrowRole::Buyer, "buyer-1".to_string(), Network::Testnet).unwrap();
184 let (seller, _) = create_participant(EscrowRole::Seller, "seller-1".to_string(), Network::Testnet).unwrap();
185 let (arbiter, _) = create_participant(EscrowRole::Arbiter, "arbiter-1".to_string(), Network::Testnet).unwrap();
186
187 manager
188 .add_participant(&contract_id, buyer, "test-agent".to_string())
189 .unwrap();
190 manager
191 .add_participant(&contract_id, seller, "test-agent".to_string())
192 .unwrap();
193 manager
194 .add_participant(&contract_id, arbiter, "test-agent".to_string())
195 .unwrap();
196
197 // Initialize multisig
198 let address = manager.initialize_multisig(&contract_id).unwrap();
199 assert!(!address.to_string().is_empty());
200
201 // Verify audit log
202 let entries = manager.audit().get_entries(&contract_id);
203 assert!(entries.len() >= 4); // Created + 3 participants
204 }
205}