Skip to main content

tenzro_types/
settlement.rs

1//! Settlement types for Tenzro Network
2//!
3//! This module defines types for payment settlement, service billing,
4//! and transaction finalization on the network.
5
6use crate::primitives::{Address, Hash, Timestamp};
7use crate::principal_chain::PrincipalChain;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11/// A request for settlement on Tenzro Network
12///
13/// Settlement requests represent claims for payment for services rendered.
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub struct SettlementRequest {
16    /// Request ID
17    pub request_id: String,
18    /// Service provider requesting settlement
19    pub provider: Address,
20    /// Customer being billed
21    pub customer: Address,
22    /// Service type
23    pub service_type: ServiceType,
24    /// Payment intent details
25    pub payment_intent: PaymentIntent,
26    /// Amount to settle (in smallest TNZO unit)
27    pub amount: u64,
28    /// Service details and proof
29    pub service_proof: ServiceProof,
30    /// Request timestamp
31    pub timestamp: Timestamp,
32    /// Settlement deadline
33    pub deadline: Option<Timestamp>,
34}
35
36impl SettlementRequest {
37    /// Creates a new settlement request
38    pub fn new(
39        provider: Address,
40        customer: Address,
41        service_type: ServiceType,
42        amount: u64,
43        service_proof: ServiceProof,
44    ) -> Self {
45        Self {
46            request_id: uuid::Uuid::new_v4().to_string(),
47            provider,
48            customer,
49            service_type,
50            payment_intent: PaymentIntent::Immediate,
51            amount,
52            service_proof,
53            timestamp: Timestamp::now(),
54            deadline: None,
55        }
56    }
57
58    /// Sets the payment intent
59    pub fn with_payment_intent(mut self, intent: PaymentIntent) -> Self {
60        self.payment_intent = intent;
61        self
62    }
63
64    /// Sets a settlement deadline
65    pub fn with_deadline(mut self, deadline: Timestamp) -> Self {
66        self.deadline = Some(deadline);
67        self
68    }
69
70    /// Checks if the settlement has expired
71    pub fn is_expired(&self) -> bool {
72        if let Some(deadline) = self.deadline {
73            Timestamp::now() > deadline
74        } else {
75            false
76        }
77    }
78}
79
80/// Receipt for a completed settlement
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
82pub struct SettlementReceipt {
83    /// Receipt ID
84    pub receipt_id: String,
85    /// Settlement request this receipt is for
86    pub request_id: String,
87    /// Transaction hash
88    pub transaction_hash: Hash,
89    /// Provider
90    pub provider: Address,
91    /// Customer
92    pub customer: Address,
93    /// Service type
94    pub service_type: ServiceType,
95    /// Amount settled (in smallest TNZO unit)
96    pub amount: u64,
97    /// Settlement status
98    pub status: SettlementStatus,
99    /// Settlement timestamp
100    pub settled_at: Timestamp,
101    /// Frozen principal chain for the customer (payer) — see Agent-Swarm
102    /// Spec 5. Captures the controller, KYC tier, and bond at the time of
103    /// settlement so liability is identifiable from the receipt without
104    /// recursive identity-registry walks. Resolved by the settlement
105    /// engine via a `PrincipalChainResolver`; falls back to a synthetic
106    /// anonymous chain when the customer address has no bound DID.
107    pub principal_chain: PrincipalChain,
108    /// Additional metadata
109    pub metadata: HashMap<String, String>,
110}
111
112impl SettlementReceipt {
113    /// Creates a new settlement receipt with an explicit principal chain.
114    ///
115    /// Callers must resolve the chain via a `PrincipalChainResolver`
116    /// (typically `IdentityRegistry::resolve_principal_chain`) and pass
117    /// it in. There is no implicit fallback inside the type — callers
118    /// that genuinely have no chain context should use
119    /// `principal_chain::anonymous_chain_for_address`.
120    #[allow(clippy::too_many_arguments)]
121    pub fn new(
122        request_id: String,
123        transaction_hash: Hash,
124        provider: Address,
125        customer: Address,
126        service_type: ServiceType,
127        amount: u64,
128        status: SettlementStatus,
129        principal_chain: PrincipalChain,
130    ) -> Self {
131        Self {
132            receipt_id: uuid::Uuid::new_v4().to_string(),
133            request_id,
134            transaction_hash,
135            provider,
136            customer,
137            service_type,
138            amount,
139            status,
140            settled_at: Timestamp::now(),
141            principal_chain,
142            metadata: HashMap::new(),
143        }
144    }
145
146    /// Adds metadata to the receipt
147    pub fn add_metadata(&mut self, key: String, value: String) {
148        self.metadata.insert(key, value);
149    }
150}
151
152/// Settlement status
153#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
154pub enum SettlementStatus {
155    /// Settlement is pending
156    Pending,
157    /// Settlement completed successfully
158    Completed,
159    /// Settlement failed
160    Failed,
161    /// Settlement disputed
162    Disputed,
163    /// Settlement refunded
164    Refunded,
165}
166
167/// Types of services that can be settled
168#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
169#[serde(tag = "type", content = "details")]
170pub enum ServiceType {
171    /// Model inference service
172    ModelInference {
173        /// Model ID
174        model_id: String,
175        /// Number of tokens processed
176        tokens: u32,
177    },
178    /// TEE computation service
179    TeeComputation {
180        /// Computation ID
181        computation_id: String,
182        /// Compute units used
183        compute_units: u64,
184    },
185    /// Storage service
186    Storage {
187        /// Data size (bytes)
188        data_size: u64,
189        /// Duration (seconds)
190        duration: u64,
191    },
192    /// Agent execution service
193    AgentExecution {
194        /// Agent ID
195        agent_id: String,
196        /// Task ID
197        task_id: String,
198    },
199    /// Data service
200    DataService {
201        /// Service ID
202        service_id: String,
203        /// Data volume
204        volume: u64,
205    },
206    /// Bridge service
207    Bridge {
208        /// Transfer ID
209        transfer_id: String,
210        /// Amount bridged
211        amount: u64,
212    },
213    /// HTTP 402 payment protocol service (MPP, x402)
214    HttpPayment {
215        /// Protocol used (e.g., "mpp", "x402")
216        protocol: String,
217        /// Resource URL that was paid for
218        resource: String,
219    },
220    /// Custom service
221    Custom {
222        /// Service name
223        name: String,
224        /// Service parameters
225        parameters: HashMap<String, String>,
226    },
227}
228
229impl ServiceType {
230    /// Returns the service type name
231    pub fn type_name(&self) -> &str {
232        match self {
233            Self::ModelInference { .. } => "ModelInference",
234            Self::TeeComputation { .. } => "TeeComputation",
235            Self::Storage { .. } => "Storage",
236            Self::AgentExecution { .. } => "AgentExecution",
237            Self::DataService { .. } => "DataService",
238            Self::Bridge { .. } => "Bridge",
239            Self::HttpPayment { .. } => "HttpPayment",
240            Self::Custom { .. } => "Custom",
241        }
242    }
243}
244
245/// Payment intent for settlement
246#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
247pub enum PaymentIntent {
248    /// Immediate payment required
249    Immediate,
250    /// Payment can be deferred
251    Deferred,
252    /// Payment on delivery/completion
253    OnDelivery,
254    /// Escrow-based payment
255    Escrow,
256    /// Subscription-based payment
257    Subscription,
258}
259
260/// Proof of service for settlement verification
261#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
262pub struct ServiceProof {
263    /// Proof type
264    pub proof_type: ProofType,
265    /// Proof data
266    pub proof_data: Vec<u8>,
267    /// Signatures from relevant parties
268    pub signatures: Vec<ProofSignature>,
269    /// Attestation (if service was performed in TEE)
270    pub attestation: Option<Vec<u8>>,
271}
272
273impl ServiceProof {
274    /// Creates a new service proof
275    pub fn new(proof_type: ProofType, proof_data: Vec<u8>) -> Self {
276        Self {
277            proof_type,
278            proof_data,
279            signatures: Vec::new(),
280            attestation: None,
281        }
282    }
283
284    /// Adds a signature to the proof
285    pub fn add_signature(&mut self, signature: ProofSignature) {
286        self.signatures.push(signature);
287    }
288
289    /// Adds an attestation
290    pub fn with_attestation(mut self, attestation: Vec<u8>) -> Self {
291        self.attestation = Some(attestation);
292        self
293    }
294}
295
296/// Types of service proofs
297#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
298pub enum ProofType {
299    /// Cryptographic proof
300    Cryptographic,
301    /// TEE attestation proof
302    TeeAttestation,
303    /// Multi-party signature proof
304    MultiParty,
305    /// Merkle proof
306    Merkle,
307    /// ZK proof
308    ZeroKnowledge,
309    /// Oracle verification
310    Oracle,
311}
312
313/// A signature in a service proof
314#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
315pub struct ProofSignature {
316    /// Signer address
317    pub signer: Address,
318    /// Signature bytes
319    pub signature: Vec<u8>,
320    /// Signer role
321    pub role: SignerRole,
322}
323
324/// Role of a signer in a proof
325#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
326pub enum SignerRole {
327    /// Service provider
328    Provider,
329    /// Service consumer
330    Consumer,
331    /// Third-party verifier
332    Verifier,
333    /// Oracle
334    Oracle,
335}
336
337/// Escrow configuration for settlements
338#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
339pub struct EscrowConfig {
340    /// Escrow address
341    pub escrow_address: Address,
342    /// Amount held in escrow (in smallest TNZO unit)
343    pub amount: u64,
344    /// Release conditions
345    pub release_conditions: ReleaseConditions,
346    /// Timeout (if conditions not met)
347    pub timeout: Timestamp,
348}
349
350/// Conditions for escrow release
351#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
352pub enum ReleaseConditions {
353    /// Release on provider signature
354    ProviderSignature,
355    /// Release on consumer signature
356    ConsumerSignature,
357    /// Release on both signatures
358    BothSignatures,
359    /// Release on verifier signature
360    VerifierSignature,
361    /// Release on timeout
362    Timeout,
363    /// Custom condition
364    Custom { condition: String },
365}