use std::env; use rand::Rng; use iota_streams::{ core::{println, psk::Psk, Result}, app::{ transport::{ tangle::client::{ Client, }, }, }, app_channels::api::{ pskid_from_psk, ChannelType, tangle::{ Author, Bytes, Subscriber, MessageContent, UnwrappedMessage }, }, }; #[tokio::main] async fn main() -> Result<()> { let node_url = env::var("URL").unwrap_or_else(|_| "https://api.lb-0.testnet.chrysalis2.com:443".to_string()); let mut client = Client::new_from_url(&node_url); let alph9 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ9"; // Generate a unique seed for the author let seed: &str = &(0..10) .map(|_| alph9.chars().nth(rand::thread_rng().gen_range(0, 27)).unwrap()) .collect::(); // generate presharedkey let presharedkey = rand::thread_rng().gen::<[u8; 32]>(); let mut author = Author::new(seed, ChannelType::MultiBranch, client.clone()); println!("\nAnnounce Channel"); // Create the channel with an announcement message. Make sure to save the resulting link somewhere, let announcement_link = author.send_announce()?; println!("Announcement Link: {}", &announcement_link); let psk = Psk::clone_from_slice(&presharedkey); let pskid = pskid_from_psk(&psk); author.store_psk(pskid.clone(), psk.clone()); // author sends keyload using preshared key let (_keyload_link, keyload_seq_link) = author.send_keyload(&announcement_link, &[pskid.clone()], &vec![])?; println!("Sent Keyload for Sub A: {}, seq: {:?}", _keyload_link, &keyload_seq_link); // author sends package let (signed_msg_link, signed_seq_link) = author.send_signed_packet(&announcement_link, &Bytes("".as_bytes().to_vec()), &Bytes("message from the grand author".as_bytes().to_vec()))?; println!("Sent msg from Sub author: {}, seq: {:?}", signed_msg_link, signed_seq_link); // 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()); // Receive the announcement message to start listening to the channel subscriber_a.receive_announcement(&announcement_link)?; // subscriber stores psk subscriber_a.store_psk(pskid.clone(), psk.clone()); // A new subscriber SubscriberB is added and sends a signed_packet to his branch let mut subscriber_b = Subscriber::new("SubscriberB", client.clone()); subscriber_b.receive_announcement(&announcement_link)?; let subscribe_msg_b = subscriber_b.send_subscribe(&announcement_link)?; let sub_b_pk = subscriber_b.get_pk(); author.receive_subscribe(&subscribe_msg_b)?; let (_keyload_2_link, keyload_2_seq_link) = author.send_keyload(&announcement_link, &[pskid.clone()], &vec![sub_b_pk.clone()])?; println!("Sent Keyload for Sub B: {}, seq: {:?}", _keyload_2_link.clone(), keyload_2_seq_link); subscriber_b.sync_state(); let prev_msg_link = _keyload_2_link; let message = "very basic message from b"; let (res_signed_package_b_link, res_signed_package_b_seq_link) = subscriber_b.send_signed_packet(&prev_msg_link, &Bytes("ssw".as_bytes().to_vec()), &Bytes(message.as_bytes().to_vec()))?; println!("Sent msg from Sub B: {}, seq: {:?}", res_signed_package_b_link, res_signed_package_b_seq_link); print("Sub A", subscriber_a.fetch_all_next_msgs()); print("Sub B", subscriber_b.fetch_all_next_msgs()); print("Author", author.fetch_all_next_msgs()); Ok(()) } fn print(name: &str, msg: Vec) { for r in msg { let content = &r.body; match content { MessageContent::SignedPacket { pk: _, public_payload, masked_payload, } => { println!("Received message for: {}", name); println!("public: {}", String::from_utf8(public_payload.0.to_vec()).unwrap()); println!("masked: {}", String::from_utf8(masked_payload.0.to_vec()).unwrap()) }, _ => println!("Received message for: {}, {:?}", name, content), }; //let details = client.get_link_details(&r.link)?; println!("prev link: {}", &r.prev_link); println!("link: {}", &r.link); //println!("id: {}\n", details.metadata.message_id); }; }