1use crate::error::{Error, Result};
4use crate::message::policy::{Policy, RequireProofOfControl};
5use crate::message::tap_message_trait::{Authorizable, TapMessageBody};
6use crate::message::{
7 AddAgents, Authorize, Participant, RemoveAgent, ReplaceAgent, Settle, Transfer,
8};
9
10use crate::didcomm::PlainMessage;
11use serde_json;
12use std::collections::HashMap;
13use std::str::FromStr;
14use tap_caip::AssetId;
15
16pub fn create_reply_to_transfer_example() -> Result<PlainMessage> {
18 let alice_did = "did:example:alice";
19 let bob_did = "did:example:bob";
20
21 let transfer = Transfer {
23 transaction_id: uuid::Uuid::new_v4().to_string(),
24 asset: AssetId::from_str("eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
25 .unwrap(),
26 originator: Participant {
27 id: alice_did.to_string(),
28 role: Some("originator".to_string()),
29 policies: None,
30 leiCode: None,
31 name: None,
32 },
33 beneficiary: Some(Participant {
34 id: bob_did.to_string(),
35 role: Some("beneficiary".to_string()),
36 policies: None,
37 leiCode: None,
38 name: None,
39 }),
40 amount: "100.00".to_string(),
41 agents: vec![],
42 settlement_id: None,
43 memo: None,
44 metadata: HashMap::new(),
45 };
46
47 let transfer_message = transfer.to_didcomm_with_route(alice_did, [bob_did].iter().copied())?;
49
50 let authorize = Authorize {
52 transaction_id: transfer_message.id.clone(),
53 note: Some("I authorize this transfer".to_string()),
54 };
55
56 let mut authorize_reply = authorize.to_didcomm(alice_did)?;
58
59 authorize_reply.thid = Some(transfer_message.id.clone());
61
62 let recipients: Vec<String> = [alice_did, bob_did]
64 .iter()
65 .filter(|&did| *did != alice_did)
66 .map(|s| s.to_string())
67 .collect();
68
69 authorize_reply.to = recipients;
70
71 Ok(authorize_reply)
72}
73
74pub fn create_reply_using_message_trait_example(
76 original_message: &PlainMessage,
77 creator_did: &str,
78) -> Result<PlainMessage> {
79 let authorize = Authorize {
81 transaction_id: original_message.id.clone(),
82 note: Some("Transfer authorized".to_string()),
83 };
84
85 let mut response_message = authorize.to_didcomm(creator_did)?;
88
89 response_message.thid = original_message.thid.clone();
91
92 let recipients: Vec<String> = original_message
94 .to
95 .iter()
96 .filter(|did| did.as_str() != creator_did)
97 .cloned()
98 .collect();
99
100 response_message.to = recipients;
101
102 Ok(response_message)
103}
104
105pub fn create_add_agents_example() -> Result<PlainMessage> {
107 let originator_did = "did:example:originator";
108 let beneficiary_did = "did:example:beneficiary";
109 let sender_vasp_did = "did:example:sender_vasp";
110 let receiver_vasp_did = "did:example:receiver_vasp";
111 let new_agent_did = "did:example:new_agent";
112
113 let transfer = Transfer {
115 transaction_id: uuid::Uuid::new_v4().to_string(),
116 asset: AssetId::from_str("eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
117 .unwrap(),
118 originator: Participant {
119 id: originator_did.to_string(),
120 role: Some("originator".to_string()),
121 policies: None,
122 leiCode: None,
123 name: None,
124 },
125 beneficiary: Some(Participant {
126 id: beneficiary_did.to_string(),
127 role: Some("beneficiary".to_string()),
128 policies: None,
129 leiCode: None,
130 name: None,
131 }),
132 amount: "100.00".to_string(),
133 memo: None,
134 agents: vec![
135 Participant {
136 id: sender_vasp_did.to_string(),
137 role: Some("sender_vasp".to_string()),
138 policies: None,
139 leiCode: None,
140 name: None,
141 },
142 Participant {
143 id: receiver_vasp_did.to_string(),
144 role: Some("receiver_vasp".to_string()),
145 policies: None,
146 leiCode: None,
147 name: None,
148 },
149 ],
150 settlement_id: None,
151 metadata: HashMap::new(),
152 };
153
154 let transfer_message =
156 transfer.to_didcomm_with_route(originator_did, [beneficiary_did].iter().copied())?;
157
158 let authorize = Authorize {
160 transaction_id: transfer_message.id.clone(),
161 note: Some("I authorize this transfer".to_string()),
162 };
163
164 let mut authorize_message = authorize.to_didcomm(originator_did)?;
166
167 authorize_message.thid = Some(transfer_message.id.clone());
169
170 let recipients: Vec<String> = [originator_did, beneficiary_did]
172 .iter()
173 .filter(|&did| *did != originator_did)
174 .map(|s| s.to_string())
175 .collect();
176
177 authorize_message.to = recipients;
178
179 let add_agents = AddAgents {
181 transaction_id: transfer_message.id.clone(),
182 agents: vec![Participant {
183 id: new_agent_did.to_string(),
184 role: Some("compliance".to_string()),
185 policies: None,
186 leiCode: None,
187 name: None,
188 }],
189 };
190
191 let mut response = add_agents.to_didcomm(originator_did)?;
193
194 response.thid = Some(transfer_message.id.clone());
196
197 let recipients: Vec<String> = [originator_did, beneficiary_did, new_agent_did]
199 .iter()
200 .filter(|&did| *did != originator_did)
201 .map(|s| s.to_string())
202 .collect();
203
204 response.to = recipients;
205
206 Ok(response)
207}
208
209pub fn create_replace_agent_example(
211 original_message: &PlainMessage,
212 creator_did: &str,
213 original_agent_id: &str,
214 replacement_agent_id: &str,
215 replacement_agent_role: Option<&str>,
216) -> Result<PlainMessage> {
217 let original_body_json = original_message.body.clone();
219 let original_transfer: Transfer = serde_json::from_value(original_body_json)
220 .map_err(|e| Error::SerializationError(e.to_string()))?;
221
222 let replacement = Participant {
224 id: replacement_agent_id.to_string(),
225 role: replacement_agent_role.map(ToString::to_string),
226 policies: None, leiCode: None,
228 name: None,
229 };
230
231 let replace_agent_body = original_transfer.replace_agent(
233 original_message.id.clone(),
234 original_agent_id.to_string(),
235 replacement,
236 );
237
238 let mut response = replace_agent_body.to_didcomm(creator_did)?;
240
241 response.thid = original_message.thid.clone();
243
244 let recipients: Vec<String> = original_message
246 .to
247 .iter()
248 .filter(|did| did.as_str() != creator_did)
249 .cloned()
250 .collect();
251
252 response.to = recipients;
253
254 Ok(response)
255}
256
257pub fn create_remove_agent_example(
259 original_message: &PlainMessage,
260 creator_did: &str,
261 agent_to_remove: &str,
262) -> Result<PlainMessage> {
263 let original_body_json = original_message.body.clone();
265 let original_transfer: Transfer = serde_json::from_value(original_body_json)
266 .map_err(|e| Error::SerializationError(e.to_string()))?;
267
268 let remove_agent_body =
270 original_transfer.remove_agent(original_message.id.clone(), agent_to_remove.to_string());
271
272 let mut response = remove_agent_body.to_didcomm(creator_did)?;
274
275 response.thid = original_message.thid.clone();
277
278 let recipients: Vec<String> = original_message
280 .to
281 .iter()
282 .filter(|did| did.as_str() != creator_did)
283 .cloned()
284 .collect();
285
286 response.to = recipients;
287
288 Ok(response)
289}
290
291pub fn create_update_policies_example(
293 original_message: &PlainMessage,
294 creator_did: &str,
295 _recipients: &[&str],
296) -> Result<PlainMessage> {
297 let original_body_json = original_message.body.clone();
299 let original_transfer: Transfer = serde_json::from_value(original_body_json)
300 .map_err(|e| Error::SerializationError(e.to_string()))?;
301
302 let proof_policy = RequireProofOfControl {
304 from: Some(vec!["did:example:dave".to_string()]),
305 from_role: None,
306 from_agent: None,
307 address_id: "eip155:1:0x1234567890123456789012345678901234567890".to_string(),
308 purpose: Some("Please prove control of your account".to_string()),
309 };
310
311 let update_policies_body = original_transfer.update_policies(
313 original_message.id.clone(),
314 vec![Policy::RequireProofOfControl(proof_policy)],
315 );
316
317 let mut response = update_policies_body.to_didcomm(creator_did)?;
319
320 response.thid = original_message.thid.clone();
322
323 let recipients: Vec<String> = original_message
325 .to
326 .iter()
327 .filter(|did| did.as_str() != creator_did)
328 .cloned()
329 .collect();
330
331 response.to = recipients;
332
333 Ok(response)
334}
335
336pub fn settle_example(
348 transaction_id: String,
349 settlement_id: String,
350 amount: Option<String>,
351) -> Result<PlainMessage> {
352 let settle = Settle {
354 transaction_id,
355 settlement_id,
356 amount,
357 };
358
359 let settle_message = settle.to_didcomm("did:example:dave")?;
361
362 Ok(settle_message)
363}
364
365pub fn thread_participant_workflow_example() -> Result<()> {
367 let alice_did = "did:example:alice";
369 let bob_did = "did:example:bob";
370 let charlie_did = "did:example:charlie";
371 let dave_did = "did:example:dave";
372
373 let transfer = Transfer {
375 transaction_id: uuid::Uuid::new_v4().to_string(),
376 asset: AssetId::from_str("eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
377 .unwrap(),
378 originator: Participant {
379 id: alice_did.to_string(),
380 role: Some("originator".to_string()),
381 policies: None,
382 leiCode: None,
383 name: None,
384 },
385 memo: None,
386 beneficiary: Some(Participant {
387 id: bob_did.to_string(),
388 role: Some("beneficiary".to_string()),
389 policies: None,
390 leiCode: None,
391 name: None,
392 }),
393 amount: "10.00".to_string(),
394 agents: vec![],
395 settlement_id: None,
396 metadata: HashMap::new(),
397 };
398
399 let transfer_message = transfer.to_didcomm_with_route(alice_did, [bob_did].iter().copied())?;
401
402 println!("Created initial transfer message: {:?}", transfer_message);
403
404 let transfer_id = transfer_message.id.clone();
406
407 let authorize = Authorize {
409 transaction_id: transfer_message.id.clone(),
410 note: Some("Transfer approved".to_string()),
411 };
412
413 let mut authorize_message = authorize.to_didcomm(bob_did)?;
415
416 authorize_message.thid = Some(transfer_message.id.clone());
418
419 let recipients: Vec<String> = [alice_did, bob_did]
421 .iter()
422 .filter(|&did| *did != bob_did)
423 .map(|s| s.to_string())
424 .collect();
425
426 authorize_message.to = recipients;
427
428 println!("Created authorize message: {:?}", authorize_message);
429
430 let add_agents = AddAgents {
433 transaction_id: transfer_id.clone(),
434 agents: vec![Participant {
435 id: charlie_did.to_string(),
436 role: Some("observer".to_string()),
437 policies: None,
438 leiCode: None,
439 name: None,
440 }],
441 };
442
443 let mut add_agents_message = add_agents.to_didcomm(alice_did)?;
445
446 add_agents_message.thid = Some(transfer_id.clone());
448
449 let recipients: Vec<String> = [alice_did, bob_did, charlie_did]
451 .iter()
452 .filter(|&did| *did != alice_did)
453 .map(|s| s.to_string())
454 .collect();
455
456 add_agents_message.to = recipients;
457
458 println!("Created add agents message: {:?}", add_agents_message);
459
460 let replace_agent = ReplaceAgent {
462 transaction_id: transfer_id.clone(),
463 original: bob_did.to_string(),
464 replacement: Participant {
465 id: dave_did.to_string(),
466 role: Some("beneficiary".to_string()),
467 policies: None,
468 leiCode: None,
469 name: None,
470 },
471 };
472
473 let mut replace_agent_message = replace_agent.to_didcomm(bob_did)?;
475
476 replace_agent_message.thid = Some(transfer_id.clone());
478
479 let recipients: Vec<String> = [alice_did, dave_did, charlie_did]
481 .iter()
482 .filter(|&did| *did != bob_did)
483 .map(|s| s.to_string())
484 .collect();
485
486 replace_agent_message.to = recipients;
487
488 println!("Created replace agent message: {:?}", replace_agent_message);
489
490 let remove_agent = RemoveAgent {
492 transaction_id: transfer_id.clone(),
493 agent: charlie_did.to_string(),
494 };
495
496 let mut remove_agent_message = remove_agent.to_didcomm(alice_did)?;
498
499 remove_agent_message.thid = Some(transfer_id.clone());
501
502 let recipients: Vec<String> = [alice_did, dave_did, charlie_did]
504 .iter()
505 .filter(|&did| *did != alice_did)
506 .map(|s| s.to_string())
507 .collect();
508
509 remove_agent_message.to = recipients;
510
511 println!("Created remove agent message: {:?}", remove_agent_message);
512
513 println!("Step 5: Settling the transfer");
515 let settle_message = settle_example(
516 transfer_id.clone(),
517 "tx123456".to_string(),
518 Some("100.0".to_string()),
519 )?;
520
521 assert!(settle_message.to.contains(&alice_did.to_string()));
523 assert!(!settle_message.to.contains(&dave_did.to_string())); println!("Verified that the settle message is addressed correctly");
525
526 Ok(())
527}