1use serde::{Deserialize, Serialize};
20
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36pub struct ServiceFeeSchedule {
37 pub human_identity_registration: u128,
41
42 pub machine_identity_registration: u128,
46
47 pub agent_registration: u128,
51
52 pub credential_issuance: u128,
56
57 pub identity_verification: u128,
61
62 pub model_registration: u128,
66
67 pub bridge_transfer_base: u128,
71}
72
73impl Default for ServiceFeeSchedule {
74 fn default() -> Self {
75 const TNZO_DECIMALS: u32 = 18;
76 const ONE_TNZO: u128 = 10u128.pow(TNZO_DECIMALS);
77
78 Self {
79 human_identity_registration: 10 * ONE_TNZO, machine_identity_registration: 5 * ONE_TNZO, agent_registration: 5 * ONE_TNZO, credential_issuance: 2 * ONE_TNZO, identity_verification: ONE_TNZO, model_registration: 50 * ONE_TNZO, bridge_transfer_base: ONE_TNZO, }
87 }
88}
89
90impl ServiceFeeSchedule {
91 pub fn new(
93 human_identity_registration: u128,
94 machine_identity_registration: u128,
95 agent_registration: u128,
96 credential_issuance: u128,
97 identity_verification: u128,
98 model_registration: u128,
99 bridge_transfer_base: u128,
100 ) -> Self {
101 Self {
102 human_identity_registration,
103 machine_identity_registration,
104 agent_registration,
105 credential_issuance,
106 identity_verification,
107 model_registration,
108 bridge_transfer_base,
109 }
110 }
111
112 pub fn calculate_total_collected(
117 &self,
118 human_identity_count: u128,
119 machine_identity_count: u128,
120 agent_count: u128,
121 credential_count: u128,
122 verification_count: u128,
123 model_count: u128,
124 bridge_count: u128,
125 ) -> Option<u128> {
126 let total = self.human_identity_registration
127 .checked_mul(human_identity_count)?
128 .checked_add(self.machine_identity_registration.checked_mul(machine_identity_count)?)?
129 .checked_add(self.agent_registration.checked_mul(agent_count)?)?
130 .checked_add(self.credential_issuance.checked_mul(credential_count)?)?
131 .checked_add(self.identity_verification.checked_mul(verification_count)?)?
132 .checked_add(self.model_registration.checked_mul(model_count)?)?
133 .checked_add(self.bridge_transfer_base.checked_mul(bridge_count)?)?;
134 Some(total)
135 }
136}
137
138#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
158pub struct NetworkCommissionRates {
159 pub inference_commission_bps: u32,
163
164 pub tee_commission_bps: u32,
168
169 pub custody_commission_bps: u32,
173
174 pub model_hosting_commission_bps: u32,
178}
179
180impl Default for NetworkCommissionRates {
181 fn default() -> Self {
182 Self {
183 inference_commission_bps: 500, tee_commission_bps: 500, custody_commission_bps: 500, model_hosting_commission_bps: 500, }
188 }
189}
190
191impl NetworkCommissionRates {
192 pub fn new(
194 inference_commission_bps: u32,
195 tee_commission_bps: u32,
196 custody_commission_bps: u32,
197 model_hosting_commission_bps: u32,
198 ) -> Self {
199 Self {
200 inference_commission_bps,
201 tee_commission_bps,
202 custody_commission_bps,
203 model_hosting_commission_bps,
204 }
205 }
206
207 pub fn calculate_inference_commission(&self, payment_amount: u128) -> Option<u128> {
211 self.calculate_commission(payment_amount, self.inference_commission_bps)
212 }
213
214 pub fn calculate_tee_commission(&self, payment_amount: u128) -> Option<u128> {
218 self.calculate_commission(payment_amount, self.tee_commission_bps)
219 }
220
221 pub fn calculate_custody_commission(&self, payment_amount: u128) -> Option<u128> {
225 self.calculate_commission(payment_amount, self.custody_commission_bps)
226 }
227
228 pub fn calculate_model_hosting_commission(&self, payment_amount: u128) -> Option<u128> {
232 self.calculate_commission(payment_amount, self.model_hosting_commission_bps)
233 }
234
235 fn calculate_commission(&self, amount: u128, bps: u32) -> Option<u128> {
239 amount
241 .checked_mul(bps as u128)?
242 .checked_div(10000)
243 }
244
245 pub fn validate(&self) -> Result<(), &'static str> {
247 const MAX_BPS: u32 = 10000; if self.inference_commission_bps > MAX_BPS {
250 return Err("Inference commission exceeds 100%");
251 }
252 if self.tee_commission_bps > MAX_BPS {
253 return Err("TEE commission exceeds 100%");
254 }
255 if self.custody_commission_bps > MAX_BPS {
256 return Err("Custody commission exceeds 100%");
257 }
258 if self.model_hosting_commission_bps > MAX_BPS {
259 return Err("Model hosting commission exceeds 100%");
260 }
261
262 Ok(())
263 }
264}
265
266#[cfg(test)]
267mod tests {
268 use super::*;
269
270 #[test]
271 fn test_service_fee_schedule_defaults() {
272 let fees = ServiceFeeSchedule::default();
273 const ONE_TNZO: u128 = 1_000_000_000_000_000_000; assert_eq!(fees.human_identity_registration, 10 * ONE_TNZO);
276 assert_eq!(fees.machine_identity_registration, 5 * ONE_TNZO);
277 assert_eq!(fees.agent_registration, 5 * ONE_TNZO);
278 assert_eq!(fees.credential_issuance, 2 * ONE_TNZO);
279 assert_eq!(fees.identity_verification, ONE_TNZO);
280 assert_eq!(fees.model_registration, 50 * ONE_TNZO);
281 assert_eq!(fees.bridge_transfer_base, ONE_TNZO);
282 }
283
284 #[test]
285 fn test_service_fee_schedule_total_collected() {
286 let fees = ServiceFeeSchedule::default();
287 const ONE_TNZO: u128 = 1_000_000_000_000_000_000;
288
289 let total = fees.calculate_total_collected(1, 1, 1, 1, 1, 1, 1).unwrap();
291 let expected = 10 + 5 + 5 + 2 + 1 + 50 + 1; assert_eq!(total, expected * ONE_TNZO);
293 }
294
295 #[test]
296 fn test_network_commission_rates_defaults() {
297 let rates = NetworkCommissionRates::default();
298
299 assert_eq!(rates.inference_commission_bps, 500);
300 assert_eq!(rates.tee_commission_bps, 500);
301 assert_eq!(rates.custody_commission_bps, 500);
302 assert_eq!(rates.model_hosting_commission_bps, 500);
303 }
304
305 #[test]
306 fn test_commission_calculation() {
307 let rates = NetworkCommissionRates::default();
308 const ONE_HUNDRED_TNZO: u128 = 100_000_000_000_000_000_000; let commission = rates.calculate_inference_commission(ONE_HUNDRED_TNZO).unwrap();
312 assert_eq!(commission, 5_000_000_000_000_000_000);
313 }
314
315 #[test]
316 fn test_commission_validation() {
317 let valid_rates = NetworkCommissionRates::default();
318 assert!(valid_rates.validate().is_ok());
319
320 let invalid_rates = NetworkCommissionRates::new(15000, 500, 500, 500);
321 assert!(invalid_rates.validate().is_err());
322 }
323
324 #[test]
325 fn test_commission_overflow_protection() {
326 let rates = NetworkCommissionRates::default();
327
328 let result = rates.calculate_inference_commission(u128::MAX);
330 assert!(result.is_none());
332 }
333}