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