private static void handleAcceptAdd(byte[] sender_wallet, byte[] aes_key) { // Retrieve the corresponding contact Friend friend = FriendList.getFriend(sender_wallet); if (friend == null) { byte[] pub_k = FriendList.findContactPubkey(sender_wallet); if (pub_k == null) { Console.WriteLine("Contact {0} not found in presence list!", Base58Check.Base58CheckEncoding.EncodePlain(sender_wallet)); return; } friend = FriendList.addFriend(sender_wallet, pub_k, Base58Check.Base58CheckEncoding.EncodePlain(sender_wallet), aes_key, null, 0); } else { friend.aesKey = aes_key; } friend.handshakeStatus = 2; friend.generateKeys(); friend.sendKeys(2); requestNickname(friend); sendNickname(friend); FriendList.addMessage(null, friend.walletAddress, friend.nickname + " has accepted your friend request."); }
// Sends the nickname back to the sender, detects if it should fetch the sender's nickname and fetches it automatically private static void handleGetNick(byte[] sender_wallet, string text) { Friend friend = FriendList.getFriend(sender_wallet); if (friend == null) { byte[] pub_k = FriendList.findContactPubkey(sender_wallet); if (pub_k == null) { Console.WriteLine("Contact {0} not found in presence list!", Base58Check.Base58CheckEncoding.EncodePlain(sender_wallet)); foreach (Presence pr in PresenceList.presences) { Console.WriteLine("Presence: {0}", Base58Check.Base58CheckEncoding.EncodePlain(pr.wallet)); } return; } friend = new Friend(sender_wallet, pub_k, "Unknown"); FriendList.addFriend(sender_wallet, pub_k, "Unknown"); SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.getNick, new byte[1]); // Also request the nickname of the sender // Prepare the message and send to the S2 nodes StreamMessage message = new StreamMessage(); message.type = StreamMessageCode.info; message.recipient = sender_wallet; message.sender = Node.walletStorage.getPrimaryAddress(); message.transaction = new byte[1]; message.sigdata = new byte[1]; message.data = spixi_message.getBytes(); string relayip = friend.searchForRelay(); StreamProcessor.sendMessage(message, relayip); } SpixiMessage reply_spixi_message = new SpixiMessage(SpixiMessageCode.nick, Encoding.UTF8.GetBytes(Node.localStorage.nickname)); // Send the nickname message to the S2 nodes StreamMessage reply_message = new StreamMessage(); reply_message.type = StreamMessageCode.info; reply_message.recipient = friend.walletAddress; reply_message.sender = Node.walletStorage.getPrimaryAddress(); reply_message.transaction = new byte[1]; reply_message.sigdata = new byte[1]; reply_message.data = reply_spixi_message.getBytes(); StreamProcessor.sendMessage(reply_message, friend.searchForRelay()); return; }
// Thread for checking offline message queue private static void offlineLoop() { List <StreamMessage> cache = new List <StreamMessage>(); // Read the persistent offline messages offlineMessages = Node.localStorage.readOfflineMessagesFile(); // Only check for offline messages when the loop is active while (continueRunning) { bool writeToFile = false; lock (offlineMessages) { // Go through each message foreach (StreamMessage message in offlineMessages) { // Extract the public key from the Presence List byte[] pub_k = FriendList.findContactPubkey(message.recipient); if (pub_k == null) { // No public key found means the contact is still offline continue; } // Send the message sendMessage(message); // Add the message to the removal cache cache.Add(message); } // Check the removal cache for messages foreach (StreamMessage message in cache) { writeToFile = true; offlineMessages.Remove(message); } // Finally, clear the removal cache cache.Clear(); } // Save changes to the offline messages file if (writeToFile) { Node.localStorage.writeOfflineMessagesFile(offlineMessages); } // Wait 5 seconds before next round Thread.Sleep(5000); } Thread.Yield(); }
private static void handleRequestAdd(byte[] sender_wallet) { byte[] pub_k = FriendList.findContactPubkey(sender_wallet); if (pub_k == null) { Console.WriteLine("Contact {0} not found in presence list!", Base58Check.Base58CheckEncoding.EncodePlain(sender_wallet)); foreach (Presence pr in PresenceList.presences) { Console.WriteLine("Presence: {0}", Base58Check.Base58CheckEncoding.EncodePlain(pr.wallet)); } return; } FriendList.addFriend(sender_wallet, pub_k, "New Contact", false); FriendList.addMessageWithType(FriendMessageType.requestAdd, sender_wallet, ""); }
public void onRequest(byte[] wal) { if (Address.validateChecksum(wal) == false) { DisplayAlert("Invalid checksum", "Please make sure you typed the address correctly.", "OK"); return; } byte[] pubkey = FriendList.findContactPubkey(wal); if (pubkey == null) { DisplayAlert("Contact does not exist", "Try again later.", "OK"); NetworkClientManager.broadcastData(new char[] { 'M' }, ProtocolMessageCode.syncPresenceList, new byte[1], null); return; } string relayip = FriendList.getRelayHostname(wal); // TODOSPIXI //FriendList.addFriend(wal, pubkey, "Unknown"); // Connect to the contact's S2 relay first // StreamClientManager.connectToStreamNode(relayip); // Send the message to the S2 nodes byte[] recipient_address = wal; SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.requestAdd, new byte[1]); StreamMessage message = new StreamMessage(); message.type = StreamMessageCode.info; message.recipient = recipient_address; message.sender = Node.walletStorage.getPrimaryAddress(); message.data = spixi_message.getBytes(); message.transaction = new byte[1]; message.sigdata = new byte[1]; StreamProcessor.sendMessage(message, relayip); Navigation.PopAsync(Config.defaultXamarinAnimations); }
// Send an encrypted message using the S2 network public static bool sendMessage(Friend friend, StreamMessage msg, bool add_to_offline_messages = true) { // TODO this function has to be improved and node's wallet address has to be added string hostname = friend.searchForRelay(); if (friend.publicKey != null && (msg.encryptionType == StreamMessageEncryptionCode.rsa || (friend.aesKey != null && friend.chachaKey != null))) { msg.encrypt(friend.publicKey, friend.aesKey, friend.chachaKey); } else if (msg.encryptionType != StreamMessageEncryptionCode.none || !friend.online) { if (friend.publicKey == null) { byte[] pub_k = FriendList.findContactPubkey(friend.walletAddress); friend.publicKey = pub_k; } StreamClientManager.connectTo(hostname, null); // TODO replace null with node address Logging.warn("Could not send message to {0}, due to missing encryption keys, adding to offline queue!", Base58Check.Base58CheckEncoding.EncodePlain(msg.recipient)); if (add_to_offline_messages) { addOfflineMessage(msg); } return(false); } if (!StreamClientManager.sendToClient(hostname, ProtocolMessageCode.s2data, msg.getBytes(), Encoding.UTF8.GetBytes(msg.getID()))) { StreamClientManager.connectTo(hostname, null); // TODO replace null with node address Logging.warn("Could not send message to {0}, adding to offline queue!", Base58Check.Base58CheckEncoding.EncodePlain(msg.recipient)); if (add_to_offline_messages) { addOfflineMessage(msg); } return(false); } return(true); /* string pub_k = FriendList.findContactPubkey(msg.recipientAddress); * if (pub_k.Length < 1) * { * Console.WriteLine("Contact {0} not found, adding to offline queue!", msg.recipientAddress); * addOfflineMessage(msg); * return; * } * * * // Create a new IXIAN transaction * // byte[] checksum = Crypto.sha256(encrypted_message); * Transaction transaction = new Transaction(0, msg.recipientAddress, Node.walletStorage.address); * // transaction.data = Encoding.UTF8.GetString(checksum); * msg.transactionID = transaction.id; * //ProtocolMessage.broadcastProtocolMessage(ProtocolMessageCode.newTransaction, transaction.getBytes()); * * // Add message to the queue * messages.Add(msg); * * // Request a new keypair from the S2 Node * if(hostname == null) * ProtocolMessage.broadcastProtocolMessage(ProtocolMessageCode.s2generateKeys, Encoding.UTF8.GetBytes(msg.getID())); * else * { * NetworkClientManager.sendData(ProtocolMessageCode.s2generateKeys, Encoding.UTF8.GetBytes(msg.getID()), hostname); * }*/ }