Beispiel #1
0
        public static void sendFileTransferCompleted(byte[] sender, string uid)
        {
            Friend friend = FriendList.getFriend(sender);

            if (friend == null)
            {
                return;
            }

            SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.fileFullyReceived, Crypto.stringToHash(uid));

            StreamMessage message = new StreamMessage();

            message.type        = StreamMessageCode.data;
            message.recipient   = friend.walletAddress;
            message.sender      = Node.walletStorage.getPrimaryAddress();
            message.transaction = new byte[1];
            message.sigdata     = new byte[1];
            message.data        = spixi_message.getBytes();

            StreamProcessor.sendMessage(friend, message, true, true, false);
        }
Beispiel #2
0
        private void onSend()
        {
            string msgId = Crypto.hashToString(requestMsg.id);

            // send tx details to the request
            if (!requestMsg.message.StartsWith(":"))
            {
                // Create an ixian transaction and send it to the dlt network
                byte[] to = friend.walletAddress;

                IxiNumber amounti = new IxiNumber(amount);
                IxiNumber fee     = ConsensusConfig.transactionPrice;
                byte[]    from    = Node.walletStorage.getPrimaryAddress();
                byte[]    pubKey  = Node.walletStorage.getPrimaryPublicKey();

                Transaction transaction = new Transaction((int)Transaction.Type.Normal, amount, fee, to, from, null, pubKey, IxianHandler.getLastBlockHeight());

                NetworkClientManager.broadcastData(new char[] { 'M' }, ProtocolMessageCode.newTransaction, transaction.getBytes(), null);

                SpixiMessage spixi_message = new SpixiMessage(null, SpixiMessageCode.requestFundsResponse, Encoding.UTF8.GetBytes(msgId + ":" + transaction.id));

                requestMsg.message = ":" + transaction.id;

                StreamMessage message = new StreamMessage();
                message.type        = StreamMessageCode.info;
                message.recipient   = to;
                message.sender      = Node.walletStorage.getPrimaryAddress();
                message.transaction = new byte[1];
                message.sigdata     = new byte[1];
                message.data        = spixi_message.getBytes();

                StreamProcessor.sendMessage(friend, message);

                Node.localStorage.writeMessagesFile(friend.walletAddress, friend.messages);
            }

            Navigation.PopAsync(Config.defaultXamarinAnimations);
        }
        private void onRequest(string recipient, string amount)
        {
            byte[] recipient_bytes = Base58Check.Base58CheckEncoding.DecodePlain(recipient);
            Friend friend          = FriendList.getFriend(recipient_bytes);

            if (friend != null && (new IxiNumber(amount)) > 0)
            {
                FriendMessage friend_message = FriendList.addMessageWithType(null, FriendMessageType.requestFunds, friend.walletAddress, 0, amount, true);

                SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.requestFunds, Encoding.UTF8.GetBytes(amount));

                StreamMessage message = new StreamMessage();
                message.type      = StreamMessageCode.info;
                message.recipient = Base58Check.Base58CheckEncoding.DecodePlain(recipient);
                message.sender    = IxianHandler.getWalletStorage().getPrimaryAddress();
                message.data      = spixi_message.getBytes();
                message.id        = friend_message.id;

                StreamProcessor.sendMessage(friend, message);

                Navigation.PopAsync(Config.defaultXamarinAnimations);
            }// else error?
        }
        private void updateMessageReadStatus(FriendMessage message)
        {
            if (!message.read && !message.localSender && App.isInForeground)
            {
                Node.shouldRefreshContacts = true;

                message.read = true;
                Node.localStorage.writeMessages(friend.walletAddress, friend.messages);

                if (!friend.bot)
                {
                    // Send read confirmation
                    StreamMessage msg_received = new StreamMessage();
                    msg_received.type        = StreamMessageCode.info;
                    msg_received.sender      = IxianHandler.getWalletStorage().getPrimaryAddress();
                    msg_received.recipient   = friend.walletAddress;
                    msg_received.data        = new SpixiMessage(SpixiMessageCode.msgRead, message.id).getBytes();
                    msg_received.transaction = new byte[1];
                    msg_received.sigdata     = new byte[1];

                    StreamProcessor.sendMessage(friend, msg_received, true, false, false);
                }
            }
        }
Beispiel #5
0
        public static void acceptFile(Friend friend, string uid)
        {
            using (MemoryStream m = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(m))
                {
                    writer.Write(uid);
                }

                FileTransfer transfer = getIncomingTransfer(uid);
                if (transfer == null)
                {
                    return;
                }

                Logging.info("Accepting file {0}", transfer.fileName);

                transfer.lastTimeStamp = Clock.getTimestamp();

                transfer.filePath   = String.Format("{0}/Downloads/{1}", Config.spixiUserFolder, transfer.fileName);
                transfer.fileStream = File.Create(transfer.filePath);
                transfer.fileStream.SetLength((long)transfer.fileSize);

                SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.acceptFile, m.ToArray());

                StreamMessage message = new StreamMessage();
                message.type        = StreamMessageCode.data;
                message.recipient   = friend.walletAddress;
                message.sender      = Node.walletStorage.getPrimaryAddress();
                message.transaction = new byte[1];
                message.sigdata     = new byte[1];
                message.data        = spixi_message.getBytes();

                StreamProcessor.sendMessage(friend, message);
            }
        }
        public async void onSend(string str)
        {
            if (str.Length < 1)
            {
                return;
            }

            await Task.Run(async() =>
            {
                // TODOSPIXI

                /*            // Send the message to the S2 nodes
                 *          byte[] recipient_address = friend.wallet_address;
                 *          byte[] encrypted_message = StreamProcessor.prepareSpixiMessage(SpixiMessageCode.chat, str, friend.pubkey);
                 *          // CryptoManager.lib.encryptData(Encoding.UTF8.GetBytes(string_to_send), friend.pubkey);
                 *
                 *          // Check the relay ip
                 *          string relayip = friend.getRelayIP();
                 *          if (relayip == null)
                 *          {
                 *              Logging.warn("No relay node to send message to!");
                 *              return;
                 *          }
                 *          if (relayip.Equals(node_ip, StringComparison.Ordinal) == false)
                 *          {
                 *
                 *              node_ip = relayip;
                 *              // Connect to the contact's S2 relay first
                 *              NetworkClientManager.connectToStreamNode(relayip);
                 *
                 *              // TODO: optimize this
                 *              while (NetworkClientManager.isNodeConnected(relayip) == false)
                 *              {
                 *
                 *              }
                 *          }
                 *
                 *          Message message = new Message();
                 *          message.recipientAddress = recipient_address;
                 *          message.data = encrypted_message;
                 *
                 *          StreamProcessor.sendMessage(message, node_ip);*/

                // store the message and display it
                FriendMessage friend_message = FriendList.addMessageWithType(null, FriendMessageType.standard, friend.walletAddress, str, true);

                // Finally, clear the input field
                Utils.sendUiCommand(webView, "clearInput");

                // Send the message
                SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.chat, Encoding.UTF8.GetBytes(str));

                StreamMessage message = new StreamMessage();
                message.type          = StreamMessageCode.data;
                message.recipient     = friend.walletAddress;
                message.sender        = Node.walletStorage.getPrimaryAddress();
                message.transaction   = new byte[1];
                message.sigdata       = new byte[1];
                message.data          = spixi_message.getBytes();
                message.id            = friend_message.id;

                if (friend.bot)
                {
                    message.encryptionType = StreamMessageEncryptionCode.none;
                    message.sign(IxianHandler.getWalletStorage().getPrimaryPrivateKey());
                }

                StreamProcessor.sendMessage(friend, message);
            });
        }
Beispiel #7
0
        public static FriendMessage addMessageWithType(byte[] id, FriendMessageType type, byte[] wallet_address, string message, bool local_sender = false, byte[] sender_address = null)
        {
            foreach (Friend friend in friends)
            {
                if (!friend.walletAddress.SequenceEqual(wallet_address))
                {
                    continue;
                }

                Node.shouldRefreshContacts = true;

                if (!friend.online)
                {
                    using (MemoryStream mw = new MemoryStream())
                    {
                        using (BinaryWriter writer = new BinaryWriter(mw))
                        {
                            writer.Write(wallet_address.Length);
                            writer.Write(wallet_address);

                            CoreProtocolMessage.broadcastProtocolMessage(new char[] { 'M' }, ProtocolMessageCode.getPresence, mw.ToArray(), null);
                        }
                    }
                }

                string sender_nick = "";
                if (friend.bot)
                {
                    if (!local_sender)
                    {
                        if (friend.contacts.ContainsKey(sender_address))
                        {
                            sender_nick = friend.contacts[sender_address].nick;
                        }
                        else
                        {
                            StreamProcessor.requestNickname(friend, sender_address);
                        }
                    }
                }
                else
                {
                    sender_nick = friend.nickname;
                }

                // TODO: message date should be fetched, not generated here
                FriendMessage friend_message = new FriendMessage(id, message, Clock.getTimestamp(), local_sender, type, sender_address, sender_nick);

                if (friend.bot && local_sender)
                {
                    friend_message.read = true;
                }

                friend.messages.Add(friend_message);

                // If a chat page is visible, insert the message directly
                if (friend.chat_page != null)
                {
                    friend.chat_page.insertMessage(friend_message);
                }
                else
                {
                    //CrossLocalNotifications.Current.Show(string.Format("New message from {0}",friend.nickname), message, 100, DateTime.Now.AddSeconds(1));
                }

                // Write to chat history
                Node.localStorage.writeMessagesFile(wallet_address, friend.messages);

                return(friend_message);
            }

            // No matching contact found in friendlist
            // Add the contact, then issue the message again
            // TODO: need to fetch the stage 1 public key somehow here
            // Ignoring such messages for now
            //addFriend(wallet_address, "pubkey", "Unknown");
            //addMessage(wallet_address, message);
            return(null);
        }
Beispiel #8
0
        private void onNavigating(object sender, WebNavigatingEventArgs e)
        {
            string current_url = HttpUtility.UrlDecode(e.Url);

            if (onNavigatingGlobal(current_url))
            {
                e.Cancel = true;
                return;
            }

            if (current_url.Equals("ixian:onload", StringComparison.Ordinal))
            {
                onLoaded();
            }
            else if (current_url.Equals("ixian:wallet", StringComparison.Ordinal))
            {
                // Deprecated
            }
            else if (current_url.Equals("ixian:quickscan", StringComparison.Ordinal))
            {
                ICustomQRScanner scanner = DependencyService.Get <ICustomQRScanner>();
                if (scanner != null && scanner.useCustomQRScanner())
                {
                    Logging.error("Custom scanner not implemented");
                    e.Cancel = true;
                    return;
                }
                quickScan();
            }
            else if (current_url.Contains("ixian:qrresult:"))
            {
                string[] split  = current_url.Split(new string[] { "ixian:qrresult:" }, StringSplitOptions.None);
                string   result = split[1];
                processQRResult(result);
                e.Cancel = true;
                return;
            }
            else if (current_url.Equals("ixian:newchat", StringComparison.Ordinal))
            {
                newChat();
            }
            else if (current_url.Equals("ixian:newcontact", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new ContactNewPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:sendixi", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WalletSendPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:receiveixi", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WalletReceivePage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:wixi", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WIXISendPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:avatar", StringComparison.Ordinal))
            {
                //onChangeAvatarAsync(sender, e);
            }
            else if (current_url.Equals("ixian:settings", StringComparison.Ordinal))
            {
                onSettings(sender, e);
            }
            else if (current_url.Equals("ixian:address", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new MyAddressPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:lock", StringComparison.Ordinal))
            {
                //   prepBackground();
                Navigation.PushAsync(new SetLockPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:activity", StringComparison.Ordinal))
            {
                // TODO show wallet activity screen
            }
            else if (current_url.Equals("ixian:about", StringComparison.Ordinal))
            {
#pragma warning disable CS0618 // Type or member is obsolete
                Device.OpenUri(new Uri(Config.aboutUrl));
#pragma warning restore CS0618 // Type or member is obsolete
            }
            else if (current_url.Equals("ixian:guide", StringComparison.Ordinal))
            {
#pragma warning disable CS0618 // Type or member is obsolete
                Device.OpenUri(new Uri(Config.guideUrl));
#pragma warning restore CS0618 // Type or member is obsolete
            }
            else if (current_url.Equals("ixian:backup", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new BackupPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:encpass", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new EncryptionPassword(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Contains("ixian:chat:"))
            {
                string[] split = current_url.Split(new string[] { "ixian:chat:" }, StringSplitOptions.None);
                string   id    = split[1];
                onChat(id, e);
            }
            else if (current_url.Contains("ixian:details:"))
            {
                string[] split = current_url.Split(new string[] { "ixian:details:" }, StringSplitOptions.None);
                string   id    = split[1];
                // TODO: handle exceptions
                byte[] id_bytes = Base58Check.Base58CheckEncoding.DecodePlain(id);

                Friend friend = FriendList.getFriend(id_bytes);

                if (friend == null)
                {
                    e.Cancel = true;
                    return;
                }

                Navigation.PushAsync(new ContactDetails(friend), Config.defaultXamarinAnimations);
            }
            else if (current_url.Contains("ixian:txdetails:"))
            {
                string[] split  = current_url.Split(new string[] { "ixian:txdetails:" }, StringSplitOptions.None);
                string   id     = split[1];
                byte[]   b_txid = Transaction.txIdLegacyToV8(id);

                Transaction transaction = null;
                foreach (Transaction tx in TransactionCache.transactions)
                {
                    if (tx.id.SequenceEqual(b_txid))
                    {
                        transaction = tx;
                        break;
                    }
                }

                if (transaction == null)
                {
                    foreach (Transaction tx in TransactionCache.unconfirmedTransactions)
                    {
                        if (tx.id.SequenceEqual(b_txid))
                        {
                            transaction = tx;
                            break;
                        }
                    }

                    if (transaction == null)
                    {
                        e.Cancel = true;
                        return;
                    }
                }

                Navigation.PushAsync(new WalletSentPage(transaction), Config.defaultXamarinAnimations);
            }
            else if (current_url.Contains("ixian:tab:"))
            {
                currentTab = current_url.Split(new string[] { "ixian:tab:" }, StringSplitOptions.None)[1];
            }
            else if (current_url.Equals("ixian:apps", StringComparison.Ordinal))
            {
                //   prepBackground();
                Navigation.PushAsync(new AppsPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:downloads", StringComparison.Ordinal))
            {
                //   prepBackground();
                Navigation.PushAsync(new DownloadsPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.StartsWith("ixian:viewLog"))
            {
                // TODO perhaps move this whole functionality to Logging class and delete spixi.log.zip on start if exists

                if (File.Exists(Path.Combine(Config.spixiUserFolder, "spixi.log.zip")))
                {
                    File.Delete(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"));
                }

                if (File.Exists(Path.Combine(Config.spixiUserFolder, "ixian.log.tmp")))
                {
                    File.Delete(Path.Combine(Config.spixiUserFolder, "ixian.log.tmp"));
                }

                File.Copy(Path.Combine(Config.spixiUserFolder, "ixian.log"), Path.Combine(Config.spixiUserFolder, "ixian.log.tmp"));

                using (ZipArchive archive = ZipFile.Open(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"), ZipArchiveMode.Create))
                {
                    archive.CreateEntryFromFile(Path.Combine(Config.spixiUserFolder, "ixian.log.tmp"), "ixian.log");
                    if (File.Exists(Path.Combine(Config.spixiUserFolder, "ixian.0.log")))
                    {
                        archive.CreateEntryFromFile(Path.Combine(Config.spixiUserFolder, "ixian.0.log"), "ixian.0.log");
                    }
                }

                if (File.Exists(Path.Combine(Config.spixiUserFolder, "ixian.log.tmp")))
                {
                    File.Delete(Path.Combine(Config.spixiUserFolder, "ixian.log.tmp"));
                }

                DependencyService.Get <IFileOperations>().share(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"), "Share Spixi Log File");
            }
            else if (current_url.StartsWith("ixian:onboardingComplete"))
            {
                Application.Current.Properties["onboardingComplete"] = true;
                Application.Current.SavePropertiesAsync();  // Force-save properties for compatibility with WPF

                SpixiLocalization.addCustomString("OnboardingComplete", "true");
                generatePage("index.html");
            }
            else if (current_url.StartsWith("ixian:joinBot"))
            {
                Friend friend = FriendList.addFriend(Base58Check.Base58CheckEncoding.DecodePlain("419jmKRKVFcsjmwpDF1XSZ7j1fez6KWaekpiawHvrpyZ8TPVmH1v6bhT2wFc1uddV"), null, "Spixi Group Chat", null, null, 0);
                if (friend != null)
                {
                    friend.save();

                    StreamProcessor.sendContactRequest(friend);
                }
            }
            else
            {
                // Otherwise it's just normal navigation
                e.Cancel = false;
                return;
            }
            e.Cancel = true;
        }
Beispiel #9
0
        public static FriendMessage addMessageWithType(byte[] id, FriendMessageType type, byte[] wallet_address, int channel, string message, bool local_sender = false, byte[] sender_address = null, long timestamp = 0, bool fire_local_notification = true, int payable_data_len = 0)
        {
            Friend friend = getFriend(wallet_address);

            if (friend == null)
            {
                // No matching contact found in friendlist
                // Add the contact, then issue the message again?
                // TODO: need to fetch the stage 1 public key somehow here
                // Ignoring such messages for now
                //addFriend(wallet_address, "pubkey", "Unknown");
                //addMessage(wallet_address, message);

                Logging.warn("Received message but contact isn't in our contact list.");
                return(null);
            }

            if (!friend.online)
            {
                using (MemoryStream mw = new MemoryStream())
                {
                    using (BinaryWriter writer = new BinaryWriter(mw))
                    {
                        writer.WriteIxiVarInt(wallet_address.Length);
                        writer.Write(wallet_address);

                        CoreProtocolMessage.broadcastProtocolMessage(new char[] { 'M', 'H' }, ProtocolMessageCode.getPresence2, mw.ToArray(), null);
                    }
                }
            }

            bool set_read = false;

            string sender_nick = "";

            if (friend.bot && sender_address != null)
            {
                if (IxianHandler.getWalletStorage().isMyAddress(sender_address))
                {
                    if (!local_sender)
                    {
                        set_read = true;
                    }
                    local_sender = true;
                }
                if (!local_sender)
                {
                    if (friend.users.hasUser(sender_address) && friend.users.getUser(sender_address).getNick() != "")
                    {
                        sender_nick = friend.users.getUser(sender_address).getNick();
                    }
                    else
                    {
                        if (!friend.users.hasUser(sender_address) || friend.users.getUser(sender_address).publicKey == null)
                        {
                            StreamProcessor.requestBotUser(friend, sender_address);
                        }
                    }
                }
            }
            else
            {
                sender_nick = friend.nickname;
            }

            if (timestamp == 0)
            {
                timestamp = Clock.getTimestamp();
            }

            FriendMessage friend_message = new FriendMessage(id, message, timestamp, local_sender, type, sender_address, sender_nick);

            friend_message.payableDataLen = payable_data_len;

            List <FriendMessage> messages = friend.getMessages(channel);

            if (messages == null)
            {
                Logging.warn("Message with id {0} was sent to invalid channel {1}.", Crypto.hashToString(id), channel);
                return(null);
            }
            lock (messages)
            {
                // TODO should be optimized
                if (id != null)
                {
                    FriendMessage tmp_msg = messages.Find(x => x.id != null && x.id.SequenceEqual(id));

                    if (tmp_msg != null)
                    {
                        if (!tmp_msg.localSender)
                        {
                            Logging.warn("Message with id {0} was already in message list.", Crypto.hashToString(id));
                        }
                        else
                        {
                            friend.setMessageRead(channel, id);
                        }
                        if (messages.Last() == tmp_msg)
                        {
                            friend.metaData.setLastMessage(tmp_msg, channel);
                            friend.metaData.setLastReceivedMessageIds(tmp_msg.id, channel);
                            friend.saveMetaData();
                        }
                        return(null);
                    }
                    else
                    {
                        friend.metaData.setLastReceivedMessageIds(friend_message.id, channel);
                    }
                }
                else if (!local_sender)
                {
                    Logging.error("Message id sent by {0} is null!", Base58Check.Base58CheckEncoding.EncodePlain(friend.walletAddress));
                    return(null);
                }
                messages.Add(friend_message);
            }

            bool old_message = false;

            // Check if the message was sent before the friend was added to the contact list
            if (friend.addedTimestamp > friend_message.timestamp)
            {
                old_message = true;
            }

            if (set_read || old_message)
            {
                friend_message.confirmed = true;
                friend_message.read      = true;
            }

            friend.metaData.setLastMessage(friend_message, channel);
            friend.saveMetaData();

            // If a chat page is visible, insert the message directly
            if (friend.chat_page != null)
            {
                friend.chat_page.insertMessage(friend_message, channel);
            }
            else if (!set_read)
            {
                // Increase the unread counter if this is a new message
                if (!old_message)
                {
                    friend.metaData.unreadMessageCount++;
                }

                friend.saveMetaData();
            }

            UIHelpers.setContactStatus(friend.walletAddress, friend.online, friend.getUnreadMessageCount(), message, timestamp);

            // Only send alerts if this is a new message
            if (old_message == false)
            {
                // Send a local push notification if Spixi is not in the foreground
                if (fire_local_notification && !local_sender)
                {
                    if (App.isInForeground == false || friend.chat_page == null)
                    {
                        // don't fire notification for nickname and avatar
                        if (!friend_message.id.SequenceEqual(new byte[] { 4 }) && !friend_message.id.SequenceEqual(new byte[] { 5 }))
                        {
                            if (friend.bot == false ||
                                (friend.metaData.botInfo != null && friend.metaData.botInfo.sendNotification))
                            {
                                DependencyService.Get <IPushService>().showLocalNotification("Spixi", "New Message", Base58Check.Base58CheckEncoding.EncodePlain(friend.walletAddress));
                            }
                        }
                    }
                }

                ISystemAlert alert = DependencyService.Get <ISystemAlert>();
                if (alert != null)
                {
                    alert.flash();
                }
            }
            // Write to chat history
            Node.localStorage.requestWriteMessages(wallet_address, channel);

            return(friend_message);
        }
Beispiel #10
0
        public void onCreateAccount(string nick, string pass)
        {
            // Generate the account on a different thread
            new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;

                // Aquire the wake lock
                bool wake_lock_sd = DependencyService.Get <IPowerManager>().AquireLock("screenDim");
                bool wake_lock_p  = DependencyService.Get <IPowerManager>().AquireLock("partial");

                if (Node.generateWallet(pass))
                {
                    Node.start();

                    Node.localStorage.nickname = nick;
                    Node.localStorage.writeAccountFile();

                    // TODO: encrypt the password
                    Application.Current.Properties["walletpass"] = pass;
                    Application.Current.SavePropertiesAsync();  // Force-save properties for compatibility with WPF

                    // Release the wake lock
                    if (wake_lock_sd)
                    {
                        DependencyService.Get <IPowerManager>().ReleaseLock("screenDim");
                    }
                    if (wake_lock_p)
                    {
                        DependencyService.Get <IPowerManager>().ReleaseLock("partial");
                    }

                    Device.BeginInvokeOnMainThread(() => {
                        Navigation.PushAsync(HomePage.Instance(), Config.defaultXamarinAnimations);
                        Navigation.RemovePage(this);
                    });

                    Friend friend = FriendList.addFriend(Base58Check.Base58CheckEncoding.DecodePlain("419jmKRKVFcsjmwpDF1XSZ7j1fez6KWaekpiawHvrpyZ8TPVmH1v6bhT2wFc1uddV"), null, "Spixi Group Chat", null, null, 0);

                    FriendList.saveToStorage();

                    StreamProcessor.sendContactRequest(friend);
                }
                else
                {
                    // Release the wake lock
                    if (wake_lock_sd)
                    {
                        DependencyService.Get <IPowerManager>().ReleaseLock("screenDim");
                    }
                    if (wake_lock_p)
                    {
                        DependencyService.Get <IPowerManager>().ReleaseLock("partial");
                    }

                    Device.BeginInvokeOnMainThread(() => {
                        displaySpixiAlert("Error", "Cannot generate new wallet. Please try again.", "Ok");
                    });
                    return;
                }
            }).Start();
        }
        public void onSend(string str)
        {
            if (str.Length < 1)
            {
                return;
            }

            // TODOSPIXI

            /*            // Send the message to the S2 nodes
             *          byte[] recipient_address = friend.wallet_address;
             *          byte[] encrypted_message = StreamProcessor.prepareSpixiMessage(SpixiMessageCode.chat, str, friend.pubkey);
             *          // CryptoManager.lib.encryptData(Encoding.UTF8.GetBytes(string_to_send), friend.pubkey);
             *
             *          // Check the relay ip
             *          string relayip = friend.getRelayIP();
             *          if (relayip == null)
             *          {
             *              Logging.warn("No relay node to send message to!");
             *              return;
             *          }
             *          if (relayip.Equals(node_ip, StringComparison.Ordinal) == false)
             *          {
             *
             *              node_ip = relayip;
             *              // Connect to the contact's S2 relay first
             *              NetworkClientManager.connectToStreamNode(relayip);
             *
             *              // TODO: optimize this
             *              while (NetworkClientManager.isNodeConnected(relayip) == false)
             *              {
             *
             *              }
             *          }
             *
             *          Message message = new Message();
             *          message.recipientAddress = recipient_address;
             *          message.data = encrypted_message;
             *
             *          StreamProcessor.sendMessage(message, node_ip);*/

            SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.chat, Encoding.UTF8.GetBytes(str));


            StreamMessage message = new StreamMessage();

            message.type        = StreamMessageCode.data;
            message.recipient   = friend.walletAddress;
            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);

            // Finally, add the text bubble visually
            DateTime      dt  = DateTime.Now;
            FriendMessage msg = new FriendMessage(str, String.Format("{0:t}", dt), false);

            friend.messages.Add(msg);
            insertMessage(msg);

            // Finally, clear the input field
            webView.Eval("clearInput()");
        }
Beispiel #12
0
        public async Task onSendFile()
        {
            // Show file picker and send the file
            try
            {
                Stream stream   = null;
                string fileName = null;
                string filePath = null;

                // Special case for iOS platform
                if (Device.RuntimePlatform == Device.iOS)
                {
                    var picker_service = DependencyService.Get <IPicturePicker>();

                    SpixiImageData spixi_img_data = await picker_service.PickImageAsync();

                    stream = spixi_img_data.stream;

                    if (stream == null)
                    {
                        return;
                    }

                    fileName = spixi_img_data.name;
                    filePath = spixi_img_data.path;
                }
                else
                {
                    FileData fileData = await CrossFilePicker.Current.PickFile();

                    if (fileData == null)
                    {
                        return; // User canceled file picking
                    }
                    stream = fileData.GetStream();

                    fileName = fileData.FileName;
                    filePath = fileData.FilePath;
                }

                FileTransfer transfer = TransferManager.prepareFileTransfer(fileName, stream, filePath);
                Logging.info("File Transfer uid: " + transfer.uid);

                SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.fileHeader, transfer.getBytes());

                StreamMessage message = new StreamMessage();
                message.type        = StreamMessageCode.data;
                message.recipient   = friend.walletAddress;
                message.sender      = Node.walletStorage.getPrimaryAddress();
                message.transaction = new byte[1];
                message.sigdata     = new byte[1];
                message.data        = spixi_message.getBytes();

                StreamProcessor.sendMessage(friend, message);


                string message_data = string.Format("{0}:{1}", transfer.uid, transfer.fileName);

                // store the message and display it
                FriendMessage friend_message = FriendList.addMessageWithType(message.id, FriendMessageType.fileHeader, friend.walletAddress, message_data, true);

                friend_message.transferId = transfer.uid;
                friend_message.filePath   = transfer.filePath;

                Node.localStorage.writeMessages(friend.walletAddress, friend.messages);
            }
            catch (Exception ex)
            {
                Logging.error("Exception choosing file: " + ex.ToString());
            }
        }
Beispiel #13
0
        public static bool sendFileData(Friend friend, string uid, ulong packet_number)
        {
            FileTransfer transfer = TransferManager.getOutgoingTransfer(uid);

            if (transfer == null)
            {
                return(false);
            }



            using (MemoryStream m = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(m))
                {
                    writer.Write(uid);

                    writer.Write(packet_number);

                    Logging.info("Sending file packet #{0}", packet_number);
                    byte[] data = transfer.getPacketData(packet_number);

                    // Write the data
                    if (data != null)
                    {
                        writer.Write(data.Length);
                        writer.Write(data);
                    }
                    else
                    {
                        writer.Write(0);
                    }
                }

                SpixiMessage spixi_message = new SpixiMessage(SpixiMessageCode.fileData, m.ToArray());


                StreamMessage message = new StreamMessage();
                message.type        = StreamMessageCode.data;
                message.recipient   = friend.walletAddress;
                message.sender      = Node.walletStorage.getPrimaryAddress();
                message.transaction = new byte[1];
                message.sigdata     = new byte[1];
                message.data        = spixi_message.getBytes();

                StreamProcessor.sendMessage(friend, message, false, false, false);
            }

            if (friend.chat_page != null)
            {
                ulong totalPackets = transfer.fileSize / (ulong)Config.packetDataSize;
                ulong fp           = 0;
                bool  complete     = false;
                if (totalPackets == packet_number)
                {
                    fp       = 100;
                    complete = true;
                }
                else
                {
                    fp = 100 / totalPackets * packet_number;
                }

                friend.chat_page.updateFile(uid, fp.ToString(), complete);
            }

            return(true);
        }
Beispiel #14
0
        public static FriendMessage addMessageWithType(byte[] id, FriendMessageType type, byte[] wallet_address, string message, bool local_sender = false, byte[] sender_address = null, long timestamp = 0, bool fire_local_notification = true)
        {
            Friend friend = getFriend(wallet_address);

            if (friend == null)
            {
                // No matching contact found in friendlist
                // Add the contact, then issue the message again?
                // TODO: need to fetch the stage 1 public key somehow here
                // Ignoring such messages for now
                //addFriend(wallet_address, "pubkey", "Unknown");
                //addMessage(wallet_address, message);

                Logging.warn("Received message but contact isn't in our contact list.");
                return(null);
            }

            Node.shouldRefreshContacts = true;

            if (!friend.online)
            {
                using (MemoryStream mw = new MemoryStream())
                {
                    using (BinaryWriter writer = new BinaryWriter(mw))
                    {
                        writer.Write(wallet_address.Length);
                        writer.Write(wallet_address);

                        CoreProtocolMessage.broadcastProtocolMessage(new char[] { 'M' }, ProtocolMessageCode.getPresence, mw.ToArray(), null);
                    }
                }
            }

            string sender_nick = "";

            if (friend.bot && sender_address != null)
            {
                if (IxianHandler.getWalletStorage().isMyAddress(sender_address))
                {
                    local_sender = true;
                }
                if (!local_sender)
                {
                    if (friend.contacts.ContainsKey(sender_address) && friend.contacts[sender_address].nick != "")
                    {
                        sender_nick = friend.contacts[sender_address].nick;
                    }
                    else
                    {
                        if (!friend.contacts.ContainsKey(sender_address) || friend.contacts[sender_address].publicKey == null)
                        {
                            StreamProcessor.requestPubKey(friend, sender_address);
                        }
                        StreamProcessor.requestNickname(friend, sender_address);
                    }
                }
            }
            else
            {
                sender_nick = friend.nickname;
            }

            if (timestamp == 0)
            {
                timestamp = Clock.getTimestamp();
            }

            FriendMessage friend_message = new FriendMessage(id, message, timestamp, local_sender, type, sender_address, sender_nick);

            if (friend.bot)
            {
                if (local_sender)
                {
                    friend_message.read = true;
                }
                else
                {
                    friend.lastReceivedMessageId = id;
                    saveToStorage();
                }
            }

            lock (friend.messages)
            {
                // TODO should be optimized
                if (id != null && friend.messages.Find(x => x.id != null && x.id.SequenceEqual(id)) != null)
                {
                    Logging.warn("Message with id {0} was already in message list.", Crypto.hashToString(id));
                    return(null);
                }
                friend.messages.Add(friend_message);
            }

            // If a chat page is visible, insert the message directly
            if (friend.chat_page != null)
            {
                friend.chat_page.insertMessage(friend_message);
            }

            // Send a local push notification if Spixi is not in the foreground
            if (fire_local_notification && !local_sender)
            {
                if (App.isInForeground == false || friend.chat_page == null)
                {
                    // don't fire notification for nickname and avatar
                    if (!friend_message.id.SequenceEqual(new byte[] { 4 }) && !friend_message.id.SequenceEqual(new byte[] { 5 }))
                    {
                        DependencyService.Get <IPushService>().showLocalNotification("Spixi", "New Message", Base58Check.Base58CheckEncoding.EncodePlain(friend.walletAddress));
                    }
                }
            }

            ISystemAlert alert = DependencyService.Get <ISystemAlert>();

            if (alert != null)
            {
                alert.flash();
            }

            // Write to chat history
            Node.localStorage.writeMessages(wallet_address, friend.messages);

            return(friend_message);
        }
Beispiel #15
0
        public void insertMessage(FriendMessage message)
        {
            if (friend.approved == false)
            {
                if (message.type == FriendMessageType.requestAdd)
                {
                    // Call webview methods on the main UI thread only
                    Utils.sendUiCommand(webView, "showContactRequest", "1");
                    message.read = true;
                    return;
                }
            }
            else
            {
                // Don't show if the friend is already approved
                if (message.type == FriendMessageType.requestAdd)
                {
                    return;
                }
            }

            string prefix  = "addMe";
            string avatar  = "";//Node.localStorage.getOwnAvatarPath();
            string address = "";
            string nick    = "";

            if (friend.bot)
            {
                if (message.senderAddress != null)
                {
                    address = Base58Check.Base58CheckEncoding.EncodePlain(message.senderAddress);
                }

                nick = message.senderNick;
                if (nick == "")
                {
                    nick = address;
                }
            }
            if (!message.localSender)
            {
                prefix = "addThem";
                avatar = "img/spixiavatar.png";
            }

            if (message.type == FriendMessageType.requestFunds)
            {
                string status      = "PENDING";
                string status_icon = "fa-clock";

                string amount = message.message;

                if (message.message.StartsWith("::"))
                {
                    status      = "DECLINED";
                    status_icon = "fa-exclamation-circle";
                    amount      = message.message.Substring(2);
                }
                else if (message.message.StartsWith(":"))
                {
                    Transaction transaction = TransactionCache.getTransaction(message.message.Substring(1));
                    if (transaction == null)
                    {
                        transaction = TransactionCache.getUnconfirmedTransaction(message.message.Substring(1));
                    }

                    amount = "?";

                    if (transaction != null)
                    {
                        amount = transaction.amount.ToString();

                        if (transaction.applied > 0)
                        {
                            status      = "CONFIRMED";
                            status_icon = "fa-check-circle";
                        }
                    }
                }


                if (message.localSender)
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), address, nick, avatar, "Payment request SENT", amount, status, status_icon, Clock.getRelativeTime(message.timestamp), message.localSender.ToString());
                }
                else
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), address, nick, avatar, "Payment request RECEIVED", amount, status, status_icon, Clock.getRelativeTime(message.timestamp));
                }
                message.read = true;
                return;
            }

            if (message.type == FriendMessageType.sentFunds)
            {
                message.read = true;
                Transaction transaction = TransactionCache.getTransaction(message.message);
                if (transaction == null)
                {
                    transaction = TransactionCache.getUnconfirmedTransaction(message.message);
                }

                string status      = "PENDING";
                string status_icon = "fa-clock";

                string amount = "?";

                if (transaction != null)
                {
                    if (transaction.applied > 0)
                    {
                        status      = "CONFIRMED";
                        status_icon = "fa-check-circle";
                    }
                    amount = transaction.amount.ToString();
                }

                // Call webview methods on the main UI thread only
                if (message.localSender)
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), address, nick, avatar, "Payment SENT", amount, status, status_icon, Clock.getRelativeTime(message.timestamp), message.localSender.ToString());
                }
                else
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), address, nick, avatar, "Payment RECEIVED", amount, status, status_icon, Clock.getRelativeTime(message.timestamp));
                }

                return;
            }


            if (message.type == FriendMessageType.fileHeader)
            {
                string[] split = message.message.Split(new string[] { ":" }, StringSplitOptions.None);
                if (split != null && split.Length > 1)
                {
                    string uid  = split[0];
                    string name = split[1];

                    Utils.sendUiCommand(webView, "addFile", Crypto.hashToString(message.id), address, nick, avatar, uid, name, Clock.getRelativeTime(message.timestamp), message.localSender.ToString(), message.confirmed.ToString(), message.read.ToString());
                }
            }
            else
            {
                // Normal chat message
                // Call webview methods on the main UI thread only
                Utils.sendUiCommand(webView, prefix, Crypto.hashToString(message.id), address, nick, avatar, message.message, Clock.getRelativeTime(message.timestamp), message.confirmed.ToString(), message.read.ToString());
            }

            if (!message.read && !message.localSender)
            {
                message.read = true;
                Node.localStorage.writeMessagesFile(friend.walletAddress, friend.messages);

                // Send read confirmation
                StreamMessage msg_received = new StreamMessage();
                msg_received.type           = StreamMessageCode.info;
                msg_received.sender         = IxianHandler.getWalletStorage().getPrimaryAddress();
                msg_received.recipient      = friend.walletAddress;
                msg_received.data           = new SpixiMessage(message.id, SpixiMessageCode.msgRead, null).getBytes();
                msg_received.transaction    = new byte[1];
                msg_received.sigdata        = new byte[1];
                msg_received.encryptionType = StreamMessageEncryptionCode.none;

                StreamProcessor.sendMessage(friend, msg_received, true);
            }
        }
Beispiel #16
0
        public static bool fetchPushMessages(bool force = false)
        {
            if (force == false && lastUpdate + cooldownPeriod > Clock.getTimestamp())
            {
                return(false);
            }

            lastUpdate = Clock.getTimestamp();

            if (pushNotificationAuthKey == null)
            {
                if (!registerWithPushNotificationServer())
                {
                    return(false);
                }
            }

            try
            {
                string receiver = Base58Check.Base58CheckEncoding.EncodePlain(Node.walletStorage.getPrimaryAddress());

                nonce++;

                byte[] sig = Crypto.sha512(UTF8Encoding.UTF8.GetBytes(nonce + pushNotificationAuthKey));

                using (WebClient client = new WebClient())
                {
                    string url      = String.Format("{0}/fetch.php?tag={1}&nonce={2}&sig={3}", Config.pushServiceUrl, receiver, nonce, Crypto.hashToString(sig));
                    string htmlCode = client.DownloadString(url);

                    if (htmlCode.StartsWith("ERROR"))
                    {
                        if (htmlCode.StartsWith("ERROR: Nonce too low "))
                        {
                            nonce = Int32.Parse(htmlCode.Substring("ERROR: Nonce too low ".Length));
                        }
                        return(false);
                    }

                    if (htmlCode == "UNREGISTERED")
                    {
                        pushNotificationAuthKey = null;
                        registerWithPushNotificationServer();
                        return(false);
                    }

                    List <string[]> jsonResponse = JsonConvert.DeserializeObject <List <string[]> >(htmlCode);

                    if (jsonResponse != null && jsonResponse.Count > 0)
                    {
                        lastUpdate = 0; // If data was available, fetch it again without cooldown
                    }

                    foreach (string[] str in jsonResponse)
                    {
                        try
                        {
                            byte[] data = Convert.FromBase64String(str[1]);
                            if (str[2] != "")
                            {
                                byte[] pk = Convert.FromBase64String(str[2]);
                                Friend f  = FriendList.getFriend(new Address(pk).address);
                                if (f != null && pk != null)
                                {
                                    f.setPublicKey(pk);
                                }
                            }
                            StreamProcessor.receiveData(data, null);
                        }
                        catch (Exception e)
                        {
                            Logging.error("Exception occured in fetchPushMessages while parsing the json response: {0}", e);
                        }

                        try
                        {
                            nonce++;
                            sig = Crypto.sha512(UTF8Encoding.UTF8.GetBytes(nonce + pushNotificationAuthKey));

                            string id = str[0];
                            url      = String.Format("{0}/remove.php?id={1}&nonce={2}&sig={3}", Config.pushServiceUrl, id, nonce, Crypto.hashToString(sig));
                            htmlCode = client.DownloadString(url);
                        }
                        catch (Exception e)
                        {
                            Logging.error("Exception occured in fetchPushMessages while removing the message from server: {0}", e);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.error("Exception occured in fetchPushMessages: {0}", e);
                return(false);
            }

            return(true);
        }
Beispiel #17
0
        public static bool fetchPushMessages(bool force = false)
        {
            if (force == false && lastUpdate + cooldownPeriod > Clock.getTimestamp())
            {
                return(false);
            }

            lastUpdate = Clock.getTimestamp();

            try
            {
                string URI        = String.Format("{0}/fetch.php", Config.pushServiceUrl);
                string unique_uri = String.Format("{0}/uniqueid.php", Config.pushServiceUrl);

                string receiver = Base58Check.Base58CheckEncoding.EncodePlain(Node.walletStorage.getPrimaryAddress());

                WebClient uclient  = new WebClient();
                byte[]    checksum = Convert.FromBase64String(uclient.DownloadString(unique_uri));

                byte[] sig = CryptoManager.lib.getSignature(checksum, Node.walletStorage.getPrimaryPrivateKey());

                using (WebClient client = new WebClient())
                {
                    string url      = String.Format("{0}?tag={1}&sig={2}", URI, receiver, HttpUtility.UrlEncode(Convert.ToBase64String(sig)));
                    string htmlCode = client.DownloadString(url);
                    Logging.info("fetchPushMessages: {0}", htmlCode);

                    if (htmlCode == "FALSE")
                    {
                        return(false);
                    }

                    lastUpdate = 0; // If data was available, fetch it again without cooldown

                    List <string[]> jsonResponse = JsonConvert.DeserializeObject <List <string[]> >(htmlCode);

                    foreach (string[] str in jsonResponse)
                    {
                        try
                        {
                            byte[] data = Convert.FromBase64String(str[0]);
                            if (str[1] != "")
                            {
                                byte[] pk = Convert.FromBase64String(str[1]);
                                Friend f  = FriendList.getFriend(new Address(pk).address);
                                if (f != null)
                                {
                                    f.publicKey = pk;
                                }
                                FriendList.saveToStorage();
                            }
                            StreamProcessor.receiveData(data, null);
                        }
                        catch (Exception e)
                        {
                            Logging.error(string.Format("Exception occured in fetchPushMessages while parsing the json response. {0}", e));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.error(string.Format("Exception occured in fetchPushMessages. {0}", e));
                return(false);
            }

            return(true);
        }