public static void completeFileTransfer(byte[] sender, string uid) { Friend friend = FriendList.getFriend(sender); if (friend == null) { return; } FileTransfer transfer = TransferManager.getIncomingTransfer(uid); if (transfer == null) { transfer = TransferManager.getOutgoingTransfer(uid); if (transfer == null) { return; } } transfer.fileStream.Dispose(); transfer.completed = true; removePacketsForFileTransfer(uid); FriendMessage fm = friend.messages.Find(x => x.transferId == uid); fm.completed = true; fm.filePath = transfer.filePath; Node.localStorage.writeMessages(friend.walletAddress, friend.messages); if (friend.chat_page != null) { friend.chat_page.updateFile(uid, "100", true); } }
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, amount, true); SpixiMessage spixi_message = new SpixiMessage(friend_message.id, SpixiMessageCode.requestFunds, Encoding.UTF8.GetBytes(amount)); StreamMessage message = new StreamMessage(); message.type = StreamMessageCode.info; message.recipient = Base58Check.Base58CheckEncoding.DecodePlain(recipient); message.sender = Node.walletStorage.getPrimaryAddress(); message.transaction = new byte[1]; message.sigdata = new byte[1]; message.data = spixi_message.getBytes(); StreamProcessor.sendMessage(friend, message); Navigation.PopAsync(Config.defaultXamarinAnimations); }// else error? }
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); }
public void onDeleteHistory() { FriendList.deleteEntireHistory(); DisplayAlert("Done", "Entire messages history deleted.", "OK"); }
private void onNavigating(object sender, WebNavigatingEventArgs e) { string current_url = HttpUtility.UrlDecode(e.Url); 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()) { Utils.sendUiCommand(webView, "quickScanJS"); 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:test", StringComparison.Ordinal)) { displaySpixiAlert("Test", current_url, "Ok"); } 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: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)) { Device.OpenUri(new Uri(Config.aboutUrl)); } 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]; byte[] id_bytes = Base58Check.Base58CheckEncoding.DecodePlain(id); Friend friend = FriendList.getFriend(id_bytes); if (friend == null) { e.Cancel = true; return; } Navigation.PushAsync(new SingleChatPage(friend), Config.defaultXamarinAnimations); } 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]; Transaction transaction = null; foreach (Transaction tx in TransactionCache.transactions) { if (tx.id.Equals(id, StringComparison.Ordinal)) { transaction = tx; break; } } if (transaction == null) { foreach (Transaction tx in TransactionCache.unconfirmedTransactions) { if (tx.id.Equals(id, StringComparison.Ordinal)) { 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 { // Otherwise it's just normal navigation e.Cancel = false; return; } e.Cancel = true; }
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); }); }
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; }
private void onNavigating(object sender, WebNavigatingEventArgs e) { string current_url = HttpUtility.UrlDecode(e.Url); 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:test", StringComparison.Ordinal)) { displaySpixiAlert("Test", current_url, "Ok"); } 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: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: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]; Transaction transaction = null; foreach (Transaction tx in TransactionCache.transactions) { if (tx.id.Equals(id, StringComparison.Ordinal)) { transaction = tx; break; } } if (transaction == null) { foreach (Transaction tx in TransactionCache.unconfirmedTransactions) { if (tx.id.Equals(id, StringComparison.Ordinal)) { 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:appAccept:")) { string session_id = current_url.Substring("ixian:appAccept:".Length); onAppAccept(session_id); } else if (current_url.StartsWith("ixian:appReject:")) { string session_id = current_url.Substring("ixian:appReject:".Length); onAppReject(session_id); } else if (current_url.StartsWith("ixian:hangUp:")) { string session_id = current_url.Substring("ixian:hangUp:".Length); VoIPManager.hangupCall(Crypto.stringToHash(session_id)); } else if (current_url.StartsWith("ixian:viewLog")) { if (File.Exists(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"))) { File.Delete(Path.Combine(Config.spixiUserFolder, "spixi.log.zip")); } using (ZipArchive archive = ZipFile.Open(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"), ZipArchiveMode.Create)) { archive.CreateEntryFromFile(Path.Combine(Config.spixiUserFolder, "ixian.log"), "ixian.log"); } DependencyService.Get <IFileOperations>().share(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"), "Share Spixi Log File"); } else { // Otherwise it's just normal navigation e.Cancel = false; return; } e.Cancel = true; }
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); }
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()); } }
public async void quickScan() { var options = new ZXing.Mobile.MobileBarcodeScanningOptions(); // Restrict to QR codes only options.PossibleFormats = new List <ZXing.BarcodeFormat>() { ZXing.BarcodeFormat.QR_CODE }; var ScannerPage = new ZXingScannerPage(options); ScannerPage.OnScanResult += (result) => { ScannerPage.IsScanning = false; Device.BeginInvokeOnMainThread(() => { Navigation.PopAsync(Config.defaultXamarinAnimations); if (result.Text.Contains(":ixi")) { string[] split = result.Text.Split(new string[] { ":ixi" }, StringSplitOptions.None); if (split.Count() < 1) { return; } string wallet_to_send = split[0]; string nickname = wallet_to_send; Friend friend = FriendList.getFriend(Base58Check.Base58CheckEncoding.DecodePlain(wallet_to_send)); if (friend != null) { nickname = friend.nickname; } webView.Eval(string.Format("addRecipient('{0}','{1}')", nickname, wallet_to_send)); return; } else if (result.Text.Contains(":send")) { // Check for transaction request string[] split = result.Text.Split(new string[] { ":send:" }, StringSplitOptions.None); if (split.Count() > 1) { string wallet_to_send = split[0]; string nickname = wallet_to_send; Friend friend = FriendList.getFriend(Base58Check.Base58CheckEncoding.DecodePlain(wallet_to_send)); if (friend != null) { nickname = friend.nickname; } webView.Eval(string.Format("addRecipient('{0}','{1}')", nickname, wallet_to_send)); return; } } else { // Handle direct addresses string wallet_to_send = result.Text; if (Address.validateChecksum(Base58Check.Base58CheckEncoding.DecodePlain(wallet_to_send))) { string nickname = wallet_to_send; Friend friend = FriendList.getFriend(Base58Check.Base58CheckEncoding.DecodePlain(wallet_to_send)); if (friend != null) { nickname = friend.nickname; } webView.Eval(string.Format("addRecipient('{0}','{1}')", nickname, wallet_to_send)); return; } } }); }; await Navigation.PushAsync(ScannerPage, Config.defaultXamarinAnimations); }
public static void completeFileTransfer(byte[] sender, string uid) { Friend friend = FriendList.getFriend(sender); if (friend == null) { return; } bool incoming = true; FileTransfer transfer = TransferManager.getIncomingTransfer(uid); if (transfer == null) { incoming = false; transfer = TransferManager.getOutgoingTransfer(uid); if (transfer == null) { return; } } transfer.fileStream.Dispose(); if (incoming && transfer.fileName != null && transfer.fileName != "") { string final_file_path = Path.Combine(downloadsPath, transfer.fileName); int instance_num = 0; while (File.Exists(final_file_path)) { instance_num++; final_file_path = Path.Combine(downloadsPath, Path.GetFileNameWithoutExtension(transfer.fileName) + "-" + instance_num.ToString() + Path.GetExtension(transfer.fileName)); } File.Move(transfer.filePath, final_file_path); transfer.filePath = final_file_path; } transfer.completed = true; removePacketsForFileTransfer(uid); FriendMessage fm = friend.getMessages(transfer.channel).Find(x => x.transferId == uid); fm.completed = true; fm.filePath = transfer.filePath; Node.localStorage.requestWriteMessages(friend.walletAddress, transfer.channel); if (incoming) { lock (incomingTransfers) { incomingTransfers.Remove(transfer); } } else { lock (outgoingTransfers) { outgoingTransfers.Remove(transfer); } } if (friend.chat_page != null) { friend.chat_page.updateFile(uid, "100", true); } }
// Called when an encryption key is received from the S2 server, as per step 4 of the WhitePaper /*private static void sendRsaEncryptedMessage(StreamMessage msg, string key, RemoteEndpoint endpoint) * { * // TODO TODO use transaction code for S2 * using (MemoryStream m = new MemoryStream()) * { * using (BinaryWriter writer = new BinaryWriter(m)) * { * writer.Write(msg.getID()); * writer.Write(msg.recipientAddress); * writer.Write(msg.transactionID); * } * } * Console.WriteLine("Sending encrypted message with key {0}", key); * * using (MemoryStream m = new MemoryStream()) * { * using (BinaryWriter writer = new BinaryWriter(m)) * { * writer.Write(msg.getID()); * writer.Write(msg.recipientAddress); * writer.Write(msg.transactionID); * * byte[] encrypted_message = CryptoManager.lib.encryptDataS2(msg.data, key); * int encrypted_count = encrypted_message.Count(); * * writer.Write(encrypted_count); * writer.Write(encrypted_message); * * byte[] ba = ProtocolMessage.prepareProtocolMessage(ProtocolMessageCode.s2data, m.ToArray()); * socket.Send(ba, SocketFlags.None); * * * // Update the DLT transaction as well * Transaction transaction = new Transaction(0, msg.recipientAddress, Node.walletStorage.address); * transaction.id = msg.transactionID; * //transaction.data = Encoding.UTF8.GetString(checksum); * //ProtocolMessage.broadcastProtocolMessage(ProtocolMessageCode.updateTransaction, transaction.getBytes()); * * } * } * }*/ // Called when receiving S2 data from clients public static void receiveData(byte[] bytes, RemoteEndpoint endpoint) { StreamMessage message = new StreamMessage(bytes); if (message.data == null) { Logging.error(string.Format("Null message data.")); return; } Logging.info("Received S2 data from {0} for {1}", Base58Check.Base58CheckEncoding.EncodePlain(message.sender), Base58Check.Base58CheckEncoding.EncodePlain(message.recipient)); Friend friend = null; // decrypt the message if necessary // TODO TODO TODO add message receive queue for when the keys aren't available yet if (message.encryptionType != StreamMessageEncryptionCode.none) { byte[] aes_key = null; byte[] chacha_key = null; friend = FriendList.getFriend(message.sender); if (friend != null) { aes_key = friend.aesKey; chacha_key = friend.chachaKey; } if (!message.decrypt(Node.walletStorage.getPrimaryPrivateKey(), aes_key, chacha_key)) { Logging.error("Could not decrypt message from {0}", Base58Check.Base58CheckEncoding.EncodePlain(friend.walletAddress)); return; } } // Extract the Spixi message SpixiMessage spixi_message = new SpixiMessage(message.data); switch (spixi_message.type) { case SpixiMessageCode.chat: { // Add the message to the friend list FriendList.addMessage(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data)); } break; case SpixiMessageCode.getNick: { // Send the nickname to the sender as requested handleGetNick(message.sender, Encoding.UTF8.GetString(spixi_message.data)); } break; case SpixiMessageCode.nick: { // Set the nickname for the corresponding address if (spixi_message.data != null) { FriendList.setNickname(message.sender, Encoding.UTF8.GetString(spixi_message.data)); } else { FriendList.setNickname(message.sender, Base58Check.Base58CheckEncoding.EncodePlain(message.sender)); } } break; case SpixiMessageCode.requestAdd: { // Friend request handleRequestAdd(spixi_message.id, message.sender, spixi_message.data); } break; case SpixiMessageCode.acceptAdd: { // Friend accepted request handleAcceptAdd(message.sender, spixi_message.data); } break; case SpixiMessageCode.sentFunds: { // Friend requested funds handleSentFunds(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data)); } break; case SpixiMessageCode.requestFunds: { // Friend requested funds handleRequestFunds(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data)); } break; case SpixiMessageCode.requestFundsResponse: { handleRequestFundsResponse(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data)); } break; case SpixiMessageCode.keys: { handleReceivedKeys(message.sender, spixi_message.data); } break; case SpixiMessageCode.msgReceived: { handleMsgReceived(message.sender, spixi_message); // don't send confirmation back, so just return return; } case SpixiMessageCode.msgRead: { handleMsgRead(message.sender, spixi_message); // don't send confirmation back, so just return return; } case SpixiMessageCode.fileHeader: { handleFileHeader(message.sender, spixi_message); } break; } if (friend == null) { friend = FriendList.getFriend(message.sender); } if (friend == null) { Logging.error("Cannot send received confirmation, friend is null"); return; } // Send received confirmation StreamMessage msg_received = new StreamMessage(); msg_received.type = StreamMessageCode.info; msg_received.sender = IxianHandler.getWalletStorage().getPrimaryAddress(); msg_received.recipient = message.sender; msg_received.data = new SpixiMessage(spixi_message.id, SpixiMessageCode.msgReceived, null).getBytes(); msg_received.transaction = new byte[1]; msg_received.sigdata = new byte[1]; msg_received.encryptionType = StreamMessageEncryptionCode.none; sendMessage(friend, msg_received, true); }
// 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); * }*/ }
// Retrieve the transaction from local cache storage private void checkTransaction() { string confirmed_text = "CONFIRMED"; Transaction ctransaction = TransactionCache.getTransaction(transaction.id); if (ctransaction == null || ctransaction.applied == 0) { ctransaction = transaction; confirmed_text = "UNCONFIRMED"; } IxiNumber amount = ctransaction.amount; string addresses = ""; byte[] addr = new Address(ctransaction.pubKey).address; if (addr.SequenceEqual(Node.walletStorage.getPrimaryAddress())) { // this is a sent payment foreach (var entry in ctransaction.toList) { Friend friend = FriendList.getFriend(entry.Key); if (friend != null) { addresses += friend.nickname + ": " + entry.Value.ToString() + "|"; } else { addresses += Base58Check.Base58CheckEncoding.EncodePlain(entry.Key) + ": " + entry.Value.ToString() + "|"; } } } else { // this is a received payment amount = 0; Utils.sendUiCommand(webView, "setReceivedMode"); byte[] sender_address = new Address(ctransaction.pubKey).address; Friend friend = FriendList.getFriend(sender_address); if (friend != null) { addresses += friend.nickname + ":|"; } else { addresses += Base58Check.Base58CheckEncoding.EncodePlain(sender_address) + ":|"; } foreach (var entry in ctransaction.toList) { if (IxianHandler.getWalletStorage().isMyAddress(entry.Key)) { // TODO show this as well under sent to; also do the reverse for sent payment //addresses += Base58Check.Base58CheckEncoding.EncodePlain(entry.Key) + ": " + entry.Value.ToString() + "|"; amount += entry.Value; } } } // Convert unix timestamp string time = Utils.UnixTimeStampToString(Convert.ToDouble(ctransaction.timeStamp)); Utils.sendUiCommand(webView, "setData", amount.ToString(), ctransaction.fee.ToString(), addresses, time, confirmed_text, (ctransaction.fee / ctransaction.amount).ToString() + "%", transaction.id); return; }
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 onDeleteHistory() { FriendList.deleteEntireHistory(); displaySpixiAlert(SpixiLocalization._SL("settings-deletedh-title"), SpixiLocalization._SL("settings-deletedh-text"), SpixiLocalization._SL("global-dialog-ok")); }
private void onBack() { Navigation.PopAsync(Config.defaultXamarinAnimations); FriendList.removeAppPage(sessionId); }