This repository has been archived by the owner on Jun 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
single_depth_private.rs
114 lines (93 loc) · 4.94 KB
/
single_depth_private.rs
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
use iota_streams::{
app::transport::tangle::client::Client,
app_channels::api::tangle::{Address, Author, Bytes, ChannelType, Subscriber},
core::{println, Result},
};
use crate::examples::{verify_messages, ALPH9};
use rand::Rng;
use core::str::FromStr;
use iota_streams::app_channels::api::tangle::MessageContent;
pub async fn example(node_url: &str) -> Result<()> {
// Generate a unique seed for the author
let seed: &str = &(0..81)
.map(|_| {
ALPH9
.chars()
.nth(rand::thread_rng().gen_range(0, 27))
.unwrap()
})
.collect::<String>();
// Create the Transport Client
let client = Client::new_from_url(node_url);
// Generate an Author
let mut author = Author::new(seed, ChannelType::SingleDepth, client.clone());
// Create the channel with an announcement message. Make sure to save the resulting link somewhere,
let announcement_link = author.send_announce().await?;
// This link acts as a root for the channel itself
let ann_link_string = announcement_link.to_string();
println!(
"Announcement Link: {}\nTangle Index: {:#}\n",
ann_link_string, announcement_link.to_msg_index()
);
// ------------------------------------------------------------------
// In their own separate instances generate the subscriber(s) that will be attaching to the channel
let mut subscriber_a = Subscriber::new("SubscriberA", client.clone());
let mut subscriber_b = Subscriber::new("SubscriberB", client);
// Generate an Address object from the provided announcement link string from the Author
let ann_address = Address::from_str(&ann_link_string)?;
// Receive the announcement message to start listening to the channel
subscriber_a.receive_announcement(&ann_address).await?;
subscriber_b.receive_announcement(&ann_address).await?;
// Send subscription messages linked to announcement message
let subscribe_msg_a = subscriber_a.send_subscribe(&ann_address).await?;
let subscribe_msg_b = subscriber_b.send_subscribe(&ann_address).await?;
// These are the subscription links that should be provided to the Author to complete subscription
let sub_msg_a_str = subscribe_msg_a.to_string();
let sub_msg_b_str = subscribe_msg_b.to_string();
println!("Subscription msgs:\n\tSubscriber A: {}\n\tTangle Index: {:#}\n\tSubscriber B: {}\n\tTangle Index: {:#}\n",
sub_msg_a_str, subscribe_msg_a.to_msg_index(), sub_msg_b_str, subscribe_msg_b.to_msg_index());
// ----------------------------------------------------------------------
// Get Address objects from subscription message links provided by expectant subscribers
let sub_a_address = Address::from_str(&sub_msg_a_str)?;
let sub_b_address = Address::from_str(&sub_msg_b_str)?;
// Author processes subscribers
author.receive_subscribe(&sub_a_address).await?;
author.receive_subscribe(&sub_b_address).await?;
// Expectant users are now subscribed and can be included in a Keyload message
// Author sends keyload with Subs A and B included (linked to announcement message). This will
// return a tuple containing the message links. The first is the message link itself, the second
// is an optional sequencing message.
// ** In single depth implementations, sequencing messages are not sent and can be ignored
let (keyload_link, _seq) = author.send_keyload_for_everyone(&announcement_link).await?;
// Author will now send signed encrypted messages in a chain
let msg_inputs = vec![
"These", "Messages", "Will", "Be", "Masked", "And", "Sent", "In", "A", "Chain",
];
// In a single depth implementation all messages will be anchored to the same message, and
// messages can be retrieved by sequence number
let anchor_msg_link = keyload_link;
for input in &msg_inputs {
let (msg_link, _seq_link) = author.send_signed_packet(
&anchor_msg_link,
&Bytes::default(),
&Bytes(input.as_bytes().to_vec()),
).await?;
println!("Sent msg: {}, tangle index: {:#}", msg_link, msg_link.to_msg_index());
}
// -----------------------------------------------------------------------------
// Subscribers can now fetch these messages
let mut retrieved = subscriber_a.fetch_all_next_msgs().await;
verify_messages(&msg_inputs, retrieved)?;
retrieved = subscriber_b.fetch_all_next_msgs().await;
verify_messages(&msg_inputs, retrieved)?;
// A message can be retreived by its sequence number and anchor message
let msg_3 = subscriber_b.receive_msg_by_sequence_number(&anchor_msg_link, 2).await?;
match msg_3.body {
MessageContent::SignedPacket { pk: _, public_payload: _, masked_payload } => {
assert_eq!(String::from_utf8(masked_payload.0)?, msg_inputs[2]);
println!("3rd Message sent matches the message retrieved");
}
_ => panic!("Not a signed packet")
}
Ok(())
}