diff --git a/FireWallet/BatchForm.cs b/FireWallet/BatchForm.cs index ca43c28..bf77044 100644 --- a/FireWallet/BatchForm.cs +++ b/FireWallet/BatchForm.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Net; using System.Runtime.InteropServices; using System.Text; -using System.Windows.Forms.VisualStyles; using Newtonsoft.Json.Linq; using ContentAlignment = System.Drawing.ContentAlignment; using Point = System.Drawing.Point; @@ -78,7 +77,6 @@ namespace FireWallet tx.Controls.Add(deleteTX); panelTXs.Controls.Add(tx); - UpdateTheme(); } public void AddBatch(string domain, string operation, decimal bid, decimal lockup) { @@ -142,7 +140,6 @@ namespace FireWallet tx.Controls.Add(deleteTX); panelTXs.Controls.Add(tx); - UpdateTheme(); } public void AddBatch(string domain, string operation, string toAddress) { @@ -202,7 +199,6 @@ namespace FireWallet tx.Controls.Add(deleteTX); panelTXs.Controls.Add(tx); - UpdateTheme(); } public void AddBatch(string domain, string operation, DNS[] updateRecords) @@ -258,7 +254,6 @@ namespace FireWallet tx.Controls.Add(deleteTX); panelTXs.Controls.Add(tx); - UpdateTheme(); } private void FixSpacing() @@ -278,7 +273,7 @@ namespace FireWallet } #endregion #region Theming - private void UpdateTheme() + public void UpdateTheme() { // Check if file exists if (!Directory.Exists(dir)) @@ -471,7 +466,7 @@ namespace FireWallet HttpClient httpClient = new HttpClient(); private async void buttonSend_Click(object sender, EventArgs e) { - if (!mainForm.WatchOnly) + if (!mainForm.WatchOnly && !mainForm.multiSig) { string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]"; string content = "{\"method\": \"sendbatch\",\"params\":[ " + batchTX + "]}"; @@ -519,6 +514,58 @@ namespace FireWallet notifyForm2.Dispose(); this.Close(); } + else if (mainForm.multiSig) + { + string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]"; + string content = "{\"method\": \"createbatch\",\"params\":[ " + batchTX + "]}"; + string responce = await APIPost("", true, content); + + if (responce == "Error") + { + AddLog("Error sending batch"); + NotifyForm notifyForm = new NotifyForm("Error sending batch"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + + JObject jObject = JObject.Parse(responce); + if (jObject["error"].ToString() != "") + { + AddLog("Error: "); + AddLog(jObject["error"].ToString()); + if (jObject["error"].ToString().Contains("Batch output addresses would exceed lookahead")) + { + NotifyForm notifyForm = new NotifyForm("Error: \nBatch output addresses would exceed lookahead\nYour batch might have too many TXs."); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + } + else if (jObject["error"].ToString().Contains("Name is not registered")) + { + NotifyForm notifyForm = new NotifyForm("Error: \nName is not registered\nRemember you can't renew domains in transfer"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + } + else + { + NotifyForm notifyForm = new NotifyForm("Error: \n" + jObject["error"].ToString()); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + } + return; + } + + string[] domains = batches.Select(batch => batch.domain).ToArray(); + string tx = await mainForm.ExportTransaction(jObject["result"].ToString(),domains); + if (tx != "Error") + { + ImportTXForm importTXForm = new ImportTXForm(mainForm, tx); + this.Hide(); + importTXForm.ShowDialog(); + importTXForm.Dispose(); + this.Close(); + } + } else // watch only { string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]"; diff --git a/FireWallet/DomainForm.cs b/FireWallet/DomainForm.cs index 3cca470..adad9d6 100644 --- a/FireWallet/DomainForm.cs +++ b/FireWallet/DomainForm.cs @@ -157,9 +157,9 @@ namespace FireWallet network = Convert.ToInt32(nodeSettings["Network"]); GetName(); - if (mainForm.WatchOnly) + if (mainForm.WatchOnly || mainForm.multiSig) { - buttonActionMain.Enabled = false; // Only allow sending in batches for ledger + buttonActionMain.Enabled = false; // Only allow sending in batches for ledger and multisig to prevent confusion } } #region API diff --git a/FireWallet/FireWallet.csproj b/FireWallet/FireWallet.csproj index 04dfcfd..386934d 100644 --- a/FireWallet/FireWallet.csproj +++ b/FireWallet/FireWallet.csproj @@ -12,7 +12,7 @@ HSDBatcher.png https://github.com/Nathanwoodburn/FireWallet git - 3.4 + 4.0 @@ -29,6 +29,7 @@ + diff --git a/FireWallet/ImportTXForm.Designer.cs b/FireWallet/ImportTXForm.Designer.cs new file mode 100644 index 0000000..2541a10 --- /dev/null +++ b/FireWallet/ImportTXForm.Designer.cs @@ -0,0 +1,223 @@ +namespace FireWallet +{ + partial class ImportTXForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImportTXForm)); + groupBoxIn = new GroupBox(); + panelIn = new Panel(); + groupBoxOut = new GroupBox(); + panelOut = new Panel(); + buttonSign = new Button(); + Cancelbutton2 = new Button(); + label1 = new Label(); + labelSigsTotal = new Label(); + labelSigsReq = new Label(); + labelSigsSigned = new Label(); + labelSigInfo = new Label(); + buttonExport = new Button(); + buttonSend = new Button(); + groupBoxIn.SuspendLayout(); + groupBoxOut.SuspendLayout(); + SuspendLayout(); + // + // groupBoxIn + // + groupBoxIn.Controls.Add(panelIn); + groupBoxIn.Location = new Point(12, 83); + groupBoxIn.Name = "groupBoxIn"; + groupBoxIn.Size = new Size(376, 355); + groupBoxIn.TabIndex = 3; + groupBoxIn.TabStop = false; + groupBoxIn.Text = "Inputs"; + // + // panelIn + // + panelIn.AutoScroll = true; + panelIn.Dock = DockStyle.Fill; + panelIn.Location = new Point(3, 19); + panelIn.Name = "panelIn"; + panelIn.Size = new Size(370, 333); + panelIn.TabIndex = 0; + // + // groupBoxOut + // + groupBoxOut.Controls.Add(panelOut); + groupBoxOut.Location = new Point(391, 80); + groupBoxOut.Name = "groupBoxOut"; + groupBoxOut.Size = new Size(484, 355); + groupBoxOut.TabIndex = 0; + groupBoxOut.TabStop = false; + groupBoxOut.Text = "Outputs"; + // + // panelOut + // + panelOut.AutoScroll = true; + panelOut.Dock = DockStyle.Fill; + panelOut.Location = new Point(3, 19); + panelOut.Name = "panelOut"; + panelOut.Size = new Size(478, 333); + panelOut.TabIndex = 0; + // + // buttonSign + // + buttonSign.FlatStyle = FlatStyle.Flat; + buttonSign.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + buttonSign.Location = new Point(700, 444); + buttonSign.Name = "buttonSign"; + buttonSign.Size = new Size(83, 36); + buttonSign.TabIndex = 2; + buttonSign.Text = "Sign"; + buttonSign.UseVisualStyleBackColor = true; + buttonSign.Click += buttonSign_Click; + // + // Cancelbutton2 + // + Cancelbutton2.FlatStyle = FlatStyle.Flat; + Cancelbutton2.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + Cancelbutton2.Location = new Point(12, 441); + Cancelbutton2.Name = "Cancelbutton2"; + Cancelbutton2.Size = new Size(83, 36); + Cancelbutton2.TabIndex = 2; + Cancelbutton2.Text = "Cancel"; + Cancelbutton2.UseVisualStyleBackColor = true; + Cancelbutton2.Click += Cancel; + // + // label1 + // + label1.AutoSize = true; + label1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + label1.Location = new Point(12, 9); + label1.Name = "label1"; + label1.Size = new Size(87, 21); + label1.TabIndex = 4; + label1.Text = "Signatures:"; + // + // labelSigsTotal + // + labelSigsTotal.BackColor = Color.Blue; + labelSigsTotal.Location = new Point(105, 7); + labelSigsTotal.Name = "labelSigsTotal"; + labelSigsTotal.Size = new Size(250, 32); + labelSigsTotal.TabIndex = 5; + // + // labelSigsReq + // + labelSigsReq.BackColor = Color.FromArgb(255, 128, 0); + labelSigsReq.Location = new Point(105, 7); + labelSigsReq.Name = "labelSigsReq"; + labelSigsReq.Size = new Size(191, 32); + labelSigsReq.TabIndex = 6; + // + // labelSigsSigned + // + labelSigsSigned.BackColor = Color.Lime; + labelSigsSigned.Location = new Point(105, 7); + labelSigsSigned.Name = "labelSigsSigned"; + labelSigsSigned.Size = new Size(100, 32); + labelSigsSigned.TabIndex = 7; + // + // labelSigInfo + // + labelSigInfo.AutoSize = true; + labelSigInfo.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + labelSigInfo.Location = new Point(361, 7); + labelSigInfo.Name = "labelSigInfo"; + labelSigInfo.Size = new Size(19, 21); + labelSigInfo.TabIndex = 8; + labelSigInfo.Text = "#"; + // + // buttonExport + // + buttonExport.Enabled = false; + buttonExport.FlatStyle = FlatStyle.Flat; + buttonExport.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + buttonExport.Location = new Point(611, 444); + buttonExport.Name = "buttonExport"; + buttonExport.Size = new Size(83, 36); + buttonExport.TabIndex = 2; + buttonExport.Text = "Export"; + buttonExport.UseVisualStyleBackColor = true; + buttonExport.Click += buttonExport_Click; + // + // buttonSend + // + buttonSend.FlatStyle = FlatStyle.Flat; + buttonSend.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + buttonSend.Location = new Point(789, 444); + buttonSend.Name = "buttonSend"; + buttonSend.Size = new Size(83, 36); + buttonSend.TabIndex = 2; + buttonSend.Text = "Send"; + buttonSend.UseVisualStyleBackColor = true; + buttonSend.Click += buttonSend_Click; + // + // ImportTXForm + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(887, 485); + Controls.Add(labelSigInfo); + Controls.Add(labelSigsSigned); + Controls.Add(labelSigsReq); + Controls.Add(labelSigsTotal); + Controls.Add(label1); + Controls.Add(groupBoxOut); + Controls.Add(groupBoxIn); + Controls.Add(buttonSend); + Controls.Add(buttonExport); + Controls.Add(Cancelbutton2); + Controls.Add(buttonSign); + FormBorderStyle = FormBorderStyle.FixedSingle; + Icon = (Icon)resources.GetObject("$this.Icon"); + MaximizeBox = false; + Name = "ImportTXForm"; + Text = "Import TX"; + Load += ImportTXForm_Load; + groupBoxIn.ResumeLayout(false); + groupBoxOut.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private GroupBox groupBoxIn; + private GroupBox groupBoxOut; + private Button buttonSign; + private Button Cancelbutton2; + private Panel panelIn; + private Panel panelOut; + private Label label1; + private Label labelSigsTotal; + private Label labelSigsReq; + private Label labelSigsSigned; + private Label labelSigInfo; + private Button buttonExport; + private Button buttonSend; + } +} \ No newline at end of file diff --git a/FireWallet/ImportTXForm.cs b/FireWallet/ImportTXForm.cs new file mode 100644 index 0000000..508dabb --- /dev/null +++ b/FireWallet/ImportTXForm.cs @@ -0,0 +1,347 @@ +using System.Windows.Forms.VisualStyles; +using Newtonsoft.Json.Linq; + +namespace FireWallet +{ + public partial class ImportTXForm : Form + { + MainForm mainForm; + JObject tx; + int totalSigs; + int reqSigs; + int sigs; + string signedTX; + string[] domains; + public ImportTXForm(MainForm mainForm) + { + InitializeComponent(); + this.mainForm = mainForm; + tx = null; + } + public ImportTXForm(MainForm mainForm, string tx) + { + InitializeComponent(); + this.mainForm = mainForm; + JObject txObj = JObject.Parse(tx); + this.tx = txObj; + } + + private void ImportTXForm_Load(object sender, EventArgs e) + { + // Default variables + domains = new string[0]; + signedTX = ""; + totalSigs = 3; + reqSigs = 2; + sigs = 0; + + // Theme + this.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]); + this.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]); + foreach (Control c in Controls) + { + mainForm.ThemeControl(c); + } + if (tx == null) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "Transaction files (*.json)|*.json"; + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + string tx = System.IO.File.ReadAllText(openFileDialog.FileName); + try + { + JObject txObj = JObject.Parse(tx); + this.tx = txObj; + } + catch + { + NotifyForm notifyForm = new NotifyForm("Invalid transaction file."); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + this.Close(); + } + } + } + ParseTX(); + } + + private void Cancel(object sender, EventArgs e) + { + this.Close(); + } + private async void ParseTX() + { + if (tx == null) this.Close(); + + string hex = tx["tx"].ToString(); + string content = "{\"method\":\"decoderawtransaction\",\"params\":[\"" + hex + "\"]}"; + string response = await mainForm.APIPost("", false, content); + if (response == null) + { + NotifyForm notifyForm = new NotifyForm("Error decoding transaction"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + JObject json = JObject.Parse(response); + if (json["error"].ToString() != "") + { + NotifyForm notifyForm = new NotifyForm("Error decoding transaction"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + JObject metadata = (JObject)tx["metadata"]; + JArray metaInputs = (JArray)metadata["inputs"]; + JArray metaOutputs = (JArray)metadata["outputs"]; + + JArray inputs = (JArray)json["result"]["vin"]; + JArray outputs = (JArray)json["result"]["vout"]; + + // Get multisig info + JObject firstIn = (JObject)inputs[0]; + JArray witnesses = (JArray)firstIn["txinwitness"]; + + string scriptSig = witnesses[witnesses.Count - 1].ToString(); + // decode script + string sigGetContent = "{\"method\":\"decodescript\",\"params\":[\"" + scriptSig + "\"]}"; + string sigGetResponse = await mainForm.APIPost("", false, sigGetContent); + if (sigGetResponse == null) + { + NotifyForm notifyForm = new NotifyForm("Error decoding transaction"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + JObject sigGetJson = JObject.Parse(sigGetResponse); + if (sigGetJson["error"].ToString() != "") + { + NotifyForm notifyForm = new NotifyForm("Error decoding transaction"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + JObject sigGetResult = (JObject)sigGetJson["result"]; + string[] asm = sigGetResult["asm"].ToString().Split(" "); + string totalSigsStr = asm[asm.Length - 2]; + totalSigs = int.Parse(totalSigsStr.Replace("OP_", "")); + reqSigs = int.Parse(sigGetResult["reqSigs"].ToString()); + sigs = -1; + for (int i = 0; i < witnesses.Count; i++) + { + string witness = witnesses[i].ToString(); + if (witness != "") + { + sigs++; + } + } + + // Set sig label sizes + labelSigsReq.Width = (labelSigsTotal.Width / totalSigs) * reqSigs; + labelSigsSigned.Width = (labelSigsTotal.Width / totalSigs) * sigs; + labelSigInfo.Text = "Signed: " + sigs + "\nReq: " + reqSigs + " of " + totalSigs; + + if (sigs >= totalSigs) + { + buttonSign.Enabled = false; + buttonSign.Text = "Signed"; + } + + for (int i = 0; i < inputs.Count; i++) + { + JObject input = (JObject)inputs[i]; + JObject metaInput = (JObject)metaInputs[i]; + + Panel PanelInput = new Panel(); + PanelInput.Size = new Size(panelIn.Width - SystemInformation.VerticalScrollBarWidth - 10, 50); + PanelInput.Location = new Point(5, panelIn.Controls.Count * 50); + PanelInput.BorderStyle = BorderStyle.FixedSingle; + + + if (metaInput.ContainsKey("sighashType")) + { + Label sighashType = new Label(); + sighashType.Text = "Sighash Type: " + metaInput["sighashType"].ToString(); + sighashType.Location = new Point(5, 25); + sighashType.AutoSize = true; + PanelInput.Controls.Add(sighashType); + } + + string txid = input["txid"].ToString(); + int vout = int.Parse(input["vout"].ToString()); + string txInfo = await mainForm.APIGet("tx/" + txid, false); + if (txInfo == "Error" || txInfo == "") + { + NotifyForm notifyForm = new NotifyForm("Error getting transaction info"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + else + { + JObject txInfoJson = JObject.Parse(txInfo); + JArray txoutputs = (JArray)txInfoJson["outputs"]; + JObject txoutput = (JObject)txoutputs[vout]; + string txoutputAddress = txoutput["address"].ToString(); + + Label address = new Label(); + string addressString = txoutputAddress.Substring(0, 5) + "..." + txoutputAddress.Substring(txoutputAddress.Length - 5, 5); + address.Text = "Address: " + addressString; + address.Location = new Point(5, 5); + address.AutoSize = true; + PanelInput.Controls.Add(address); + + Label amount = new Label(); + Decimal value = Decimal.Parse(txoutput["value"].ToString()) / 1000000; + amount.Text = "Amount: " + value.ToString(); + amount.Location = new Point(5, 25); + amount.AutoSize = true; + PanelInput.Controls.Add(amount); + + } + panelIn.Controls.Add(PanelInput); + } + + for (int i = 0; i < outputs.Count; i++) + { + JObject output = (JObject)outputs[i]; + JObject metaOutput = (JObject)metaOutputs[i]; + + Panel PanelOutput = new Panel(); + PanelOutput.Size = new Size(panelOut.Width - SystemInformation.VerticalScrollBarWidth - 10, 50); + PanelOutput.Location = new Point(5, panelOut.Controls.Count * 50); + PanelOutput.BorderStyle = BorderStyle.FixedSingle; + + Label address = new Label(); + + JObject addressRaw = (JObject)output["address"]; + + string addressString = addressRaw["string"].ToString().Substring(0, 5) + "..." + addressRaw["string"].ToString().Substring(addressRaw["string"].ToString().Length - 5, 5); + address.Text = "Address: " + addressString; + address.Location = new Point(5, 5); + address.AutoSize = true; + PanelOutput.Controls.Add(address); + + JObject covenant = (JObject)output["covenant"]; + if (covenant.ContainsKey("action")) + { + if (covenant["action"].ToString() != "NONE") + { + if (metaOutput.ContainsKey("name")) + { + Label covenantLabel = new Label(); + string name = metaOutput["name"].ToString(); + + covenantLabel.Text = covenant["action"].ToString() + ": " + name; + covenantLabel.Location = new Point(5, 25); + covenantLabel.AutoSize = true; + PanelOutput.Controls.Add(covenantLabel); + + string[] domainsNew = new string[domains.Length + 1]; + for (int j = 0; j < domains.Length; j++) + { + domainsNew[j] = domains[j]; + } + domainsNew[domainsNew.Length - 1] = name; + domains = domainsNew; + } + } + } + + bool own = false; + string addressResp = await mainForm.APIGet("wallet/" + mainForm.Account + "/key/" + addressRaw["string"].ToString(), true); + if (addressResp != "Error") own = true; + + if (own) + { + Label ownAddress = new Label(); + ownAddress.Text = "Own Address"; + ownAddress.Location = new Point(PanelOutput.Width - 150, 5); + ownAddress.AutoSize = true; + PanelOutput.Controls.Add(ownAddress); + } + + Label amount = new Label(); + Decimal value = Decimal.Parse(output["value"].ToString()); + amount.Text = "Amount: " + value.ToString(); + amount.Location = new Point(PanelOutput.Width - 150, 25); + amount.AutoSize = true; + PanelOutput.Controls.Add(amount); + panelOut.Controls.Add(PanelOutput); + } + } + + private async void buttonSign_Click(object sender, EventArgs e) + { + if (!mainForm.WatchOnly) + { + string content = "{\"tx\":\"" + tx["tx"].ToString() + "\", \"passphrase\":\"" + mainForm.Password + "\"}"; + string response = await mainForm.APIPost("wallet/" + mainForm.Account + "/sign", true, content); + if (response == "Error" || response == "") + { + NotifyForm notifyForm = new NotifyForm("Error signing transaction"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + buttonSign.Enabled = false; + buttonExport.Enabled = true; + sigs++; + // Set sig label sizes + labelSigsReq.Width = (labelSigsTotal.Width / totalSigs) * reqSigs; + labelSigsSigned.Width = (labelSigsTotal.Width / totalSigs) * sigs; + labelSigInfo.Text = "Signed: " + sigs + "\nReq: " + reqSigs + " of " + totalSigs; + signedTX = response; + } else { + NotifyForm notifyForm = new NotifyForm("Ledger signing not supported yet 😢"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + } + } + + private void buttonExport_Click(object sender, EventArgs e) + { + mainForm.ExportTransaction(signedTX,domains); + } + + private async void buttonSend_Click(object sender, EventArgs e) + { + string content = ""; + if (signedTX != "") + { + JObject signed = JObject.Parse(signedTX); + content = "{\"method\":\"sendrawtransaction\", \"params\":[\"" + signed["hex"].ToString() + "\"]}"; + } + else + { + content = "{\"method\":\"sendrawtransaction\", \"params\":[\"" + tx["tx"].ToString() + "\"]}"; + } + string response = await mainForm.APIPost("", false, content); + if (response == "Error" || response == "") + { + mainForm.AddLog(response); + NotifyForm notifyError = new NotifyForm("Error sending transaction"); + notifyError.ShowDialog(); + notifyError.Dispose(); + return; + } + JObject responseJson = JObject.Parse(response); + if (responseJson["error"].ToString() != "") + { + mainForm.AddLog(response); + JObject error = (JObject)responseJson["error"]; + NotifyForm notifyError = new NotifyForm("Error sending transaction\n" + error["message"].ToString()); + notifyError.ShowDialog(); + notifyError.Dispose(); + return; + } + string txHash = responseJson["result"].ToString(); + NotifyForm notifyForm = new NotifyForm("Transaction sent\nIf the transaction hasn't been signed it might not be mined", "Explorer", mainForm.UserSettings["explorer-tx"] + txHash); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + this.Close(); + + } + } +} diff --git a/FireWallet/ImportTXForm.resx b/FireWallet/ImportTXForm.resx new file mode 100644 index 0000000..0464da4 --- /dev/null +++ b/FireWallet/ImportTXForm.resx @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA + IACoJQAA7h4AAAAAAAABACAAfScAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI8/zACPQM0Aj0DNEo9AzVePQM02j0DNAI9AzQAAAAAAAAAAAI8/zQCPQM0Aj0DNNI9A + zViPQM0Sj0DNAI8/zACPQM0Uj0DNXY9AzcOPQM37j0DN1o9AzTuPQM0Ajz/NAI4/zACPQM0Aj0DNOY9A + zdWPQM37j0DNxI9AzV6PQM0Vj0DNso9AzfqPQM3/j0DN/49Azf+PQM3Wj0DNO49AzQCPQM0Aj0DNOY9A + zdSPQM3/j0DN/49Azf+PQM36j0DNtY9AzdmPQM3/j0DN/49Azf+PQM3/j0DN/49AzdaPQM05j0DNN49A + zdWPQM3/j0DN/49Azf+PQM3/j0DN/49AzdyRQ8XYkUPF/5FDxf+RQ8X/kUPF/5FDxf+RQ8X/kkPFsZJD + xa+RQ8X/kUPF/5FDxf+RQ8X/kUPF/5FDxf+RQ8Xbmkuu2JpLrv+aS67/mkuv/ppLrv6aS67/mkuu/5pL + r76aS6+9mkuu/5pLrv+aS67+mkuv/ppLrv+aS67/mkuu26VSkNilUpD/pVKQ/6RSkOajUZWrpVKQ+aVS + kP+lUpC+pVKQvKVSkP+lUpD6o1GVq6RSkOWlUpD/pVKQ/6VSkNuwVG3YsFRt/7BUbf+wVG3drlRzKq5U + c4+wVG3/sFRtv7BUbb6wVG3/rlRzka5UcymwVG3csFRt/7BUbf+wVG3cuVNI2blTSP+5U0j/uVNI3rlT + Rxy0VWELuFNOlblTSLq5U0i5uFNOlrRVYAy5U0cbuVNI3blTSP+5U0j/uVNI3MFQHtnBUB7/wVAe/8FQ + Ht/AUB4ewFAkAL5RMxC/USxQv1EsUL5RMxDAUCUAwFAeHMFQHt3BUB7/wVAe/8FQHtzDTwnZw08J/8NP + Cf/DTwnfw08JHsNPCQDETgAAx0wAAcdNAAHFTQAAw08JAMNPCR3DTwnew08J/8NPCf/DTwncw08J2MNP + Cf/DTwn/w08Jw8NPCRXDTwkAAAAAAAAAAAAAAAAAAAAAAMNPCQDDTwkUw08JwcNPCf/DTwn/w08J28NP + CdbDTwnbw08JfMNPCSHDTggAw08JAAAAAAAAAAAAAAAAAAAAAADCTwkAwU4HAMNPCSDDTwl7w08J28NP + CdjDTwlVw08JI8NOCAHDTwkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDTwgAwk4IAcNP + CSLDTwlWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AADH4wAAA8AAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEIAAABmAAAAfg + AAAP8AAAH/gAAP//AAAoAAAAGAAAADAAAAABACAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8/zACPP8wDjz/MAo8/ + zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8/zQCPP80Cjz/NA48/zQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQM0Ajz/NBY9AzTePQM2Wj0DNYo4/zAOPP80AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj0DNAI8/zQKPQM1gj0DNl49AzTmPP80Fjz/NAAAAAAAAAAAAjz/NAI8/zQWPQM04j0DNm49A + zeuPQM3/j0DN749AzWeOP8wDjz/NAAAAAAAAAAAAAAAAAAAAAACPP80Ajz/MAo9AzWSPQM3uj0DN/49A + zeuPQM2dj0DNOY8/zQWPQM0Aj0DNN49AzZyPQM3rj0DN/49Azf+PQM3/j0DN/49Aze+PQM1njz/MA48/ + zQAAAAAAAAAAAI9AzQCOP8wCj0DNZI9Aze6PQM3/j0DN/49Azf+PQM3/j0DN7I9AzZ6PQM05j0DNuY9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3vj0DNZo4/zAOPQMwAjz/NAI8/zQKPQM1jj0DN7o9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM2+j0DNwY9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN749AzWeOP84Djj7OAo9AzWWPQM3uj0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3Gj0DMwY9AzP+PQMz/j0DM/49AzP+PQMz/j0DM/49AzP+PQMz/j0DM/49AzPCPQMtZj0DLVo9A + zO+PQMz/j0DM/49AzP+PQMz/j0DM/49AzP+PQMz/j0DM/49AzP+PQMzFkkTDwJJEw/+SRMP/kkTD/5JE + w/+SRMP/kkTD/5JEw/+SRMP/kkTD/5JEw/+SRMOekkTDm5JEw/+SRMP/kkTD/5JEw/+SRMP/kkTD/5JE + w/+SRMP/kkTD/5JEw/+SRMPFmEqzwJhKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hK + s/+YSrOfmEqznJhKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hKs/+YSrPFn0+gwJ9P + oP+fT6D/n0+g/59PoP+fT6D2n0+h7J9PoP+fT6D/n0+g/59PoP+fT6Cfn0+gm59PoP+fT6D/n0+g/59P + oP+fT6Hsn0+g9p9PoP+fT6D/n0+g/59PoP+fT6DGp1OKwadTiv+nU4r/p1OK/6dTiv+nU4rdpVKPYqZT + jNynU4r/p1OK/6dTiv+nU4qfp1OKnKdTiv+nU4r/p1OK/6ZTjN6lUo9jp1OK26dTiv+nU4r/p1OK/6dT + iv+nU4rGrlRzwa5Uc/+uVHP/rlRz/65Uc/+uVHPdrlRzHKxUe0StVHTfrlRz/65Uc/+uVHOgrlRzna5U + c/+uVHP/rlR04KxUe0auVHMarlRz265Uc/+uVHP/rlRz/65Uc/+uVHPGtVRawbVUWv+1VFr/tVRa/7VU + Wv+1VFrdtVRaHLZTVgCzVWJHtFRc37VUWv+1VFqhtVRanbVUWv+0VFzhs1RiSbdTVAC1VFoatVRa27VU + Wv+1VFr/tVRa/7VUWv+1VFrHu1JBwbtSQf+7UkH/u1JB/7tSQf+7UkHdu1JBHbtSQgDAUikAuVNKR7tT + Q+K7UkGgu1JBnbtTQ+S5U0lJw1AYALtSQgC7UkEau1JB27tSQf+7UkH/u1JB/7tSQf+7UkHHwFAlwcBQ + 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 + zf+PQM38j0DNl48/zA+PP80AAAAAAAAAAAAAAAAAAAAAAI9AzQCPQM0Oj0DNk49AzfuPQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/Y9AzdWPQM1ej0DNp49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM38j0DNl48/zA+PQM0AAAAAAAAAAACPQM0Aj0DNDo9AzZOPQM37j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Aza6PQM2oj0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM38j0DNl48/zRCPP80Aj0DNAI8/zQ+PQM2Uj0DN+49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DNr49AzaePQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM38j0DNmo4/zQ+PP80Oj0DNlo9A + zfyPQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM2ukEHKp5BB + yv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr9kEHJZ5BB + yWKQQcr8kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/49B + yq6TRcGnk0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NF + wf+TRcGEk0XBf5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NF + wf+TRcH/k0XBrpdJtaeXSbX/l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJ + tf+XSbX/l0m1/5dJtYKXSbZ9l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJ + tf+XSbX/l0m1/5dJtf+XSbWunE2op5xNqP+cTaj/nE2o/5xNqP+cTaj/nE2o/5xNqP+cTaf/nE2o/5xN + qP+cTaj/nE2o/5xNqP+cTaj/nE2ogZxNqHycTaj/nE2o/5xNqP+cTaj/nE2o/5xNqP+cTaf/nE2o/5xN + qP+cTaj/nE2o/5xNqP+cTaj/nE2o/5xNqK6iUZinolGY/6JRmP+iUZj/olGY/6JRmP+iUZj/olGY6KFQ + mrmiUZj8olGY/6JRmP+iUZj/olGY/6JRmP+iUZiBolGYfKJRmP+iUZj/olGY/6JRmP+iUZj/olGY/KFQ + mrqiUZjnolGY/6JRmP+iUZj/olGY/6JRmP+iUZj/olGYrqhTh6eoU4f/qFOH/6hTh/+oU4f/qFOH/6hT + h/+oU4fcplOLL6dTip6oU4f9qFOH/6hTh/+oU4f/qFOH/6hTh4KnU4d9qFOH/6hTh/+oU4f/qFOH/6hT + h/6nU4qiplOLLqhTh9moU4f/qFOH/6hTh/+oU4f/qFOH/6hTh/+oU4evrVR2p61Udv+tVHb/rVR2/61U + dv+tVHb/rVR2/61UdtytVHYbqlSAEaxUeaGtVHb9rVR2/61Udv+tVHb/rVR2g61Udn6tVHb/rVR2/61U + dv+tVHb+rFR5pKpUfxOtVHYYrVR22q1Udv+tVHb/rVR2/61Udv+tVHb/rVR2/61Udq+yVGSoslVk/7JV + ZP+yVWT/slVk/7JVZP+yVWT/slVk3LJUZByxVWcAsFVtFLJVZ6KyVWT+slVk/7JVZP+yVGSEslRkf7JV + ZP+yVWT/slVk/rJVZqawVW0VsVRnALJUZBmyVGTZslVk/7JVZP+yVWT/slVk/7JVZP+yVWT/slRkr7dU + Uai3VFH/t1RR/7dUUf+3VFH/t1RR/7dUUf+3VFHct1NRHLdTUQC1VFoAtVRaFLdUVKO3VFH+t1RR/7dU + UYO3VFF+t1RR/7dUUf63VFSmtVRaFrVUWQC3U1EAt1NRGbdUUdm3VFH/t1RR/7dUUf+3VFH/t1RR/7dU + Uf+3VFGwvFI+qLxSPv+8Uj7/vFI+/7xSPv+8Uj7/vFI+/7xSPty7Uj4cu1I+AMNRHQC6U0cAulNIFLtS + QaG8Uj7/vFI+gbxSPny8Uj7/u1JBpbpTSBa6U0cAv1E0ALtSPgC7Uj4ZvFI+2bxSPv+8Uj7/vFI+/7xS + Pv+8Uj7/vFI+/7xSPrC/UCqov1Eq/79RKv+/USr/v1Eq/79RKv+/USr/v1Aq3b9QKRy/UCkAAAAAANJE + AAC+UTMAvlE0E79RLZ+/UCp6v1Eqdr9RLaK+UTQUvlEzAMNNFwAAAAAAv1ApAL9QKRm/UCrZv1Eq/79R + Kv+/USr/v1Eq/79RKv+/USr/v1AqsMJPEqjCTxL/wk8S/8JPEv/CTxL/wk8S/8JPEv/CTxLdwk8SHcJP + EgAAAAAAAAAAAAAAAADBTx4AwU8eE8FPHCfBUBwnwVAeFMFQHgD/AAAAAAAAAAAAAADCTxIAwk8SGsJP + EtrCTxL/wk8S/8JPEv/CTxL/wk8S/8JPEv/CTxKww08JqMNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + Cd7DTwgdw08IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMNP + CADDTwgaw08J2sNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCbDDTwmow08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J3sNPCR3DTwkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAw08JAMNPCRvDTwnbw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08Jr8NPCafDTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwndw08JHMNPCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADDTwkAw08JGsNPCdrDTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwmuw08Jp8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J88NPCZrDTgkMw08JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJPCQDCTwkKw08JlsNPCfLDTwn/w08J/8NPCf/DTwn/w08J/8NP + Ca3DTwmmw08J/8NPCf/DTwn/w08J8sNPCavDTwlGw08JCcNPCQDCTgcAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw08GAMNPCQDCTwgIw08JRMNPCanDTwnxw08J/8NP + Cf/DTwn/w08JrMNPCaTDTwn/w08J8cNPCazDTwlGw04ICcNPCADDTgkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFMCQDDTwkAwk8JCMNP + CUTDTwmqw08J8cNPCf/DTwmqw08JkcNPCarDTwlFw08ICcNPCQDCTAgAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADCTwYAw08JAMNPCQjDTwlDw08JqcNPCZbDTwkXw08JCcNPCQC/SwUAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAw00FAMNPCQDDTgkIw04JGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////5/ + /j/4P/wf4B/4B4AP8AAAB+AAAAPAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA + AgAAYAYAAHAOAAB4HgAAfD4AAH/+AAB//gAAf/4AAH/+AAD//wAD///AD///8D////z//////////ygA + AAAwAAAAYAAAAAEAIAAAAAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjz7LAI8+ + ywCPPssAjz7LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkDLAI4/ywCOP8sAjkDLAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5A + zACOP8wBjz/NJY9AzXmPQM1Ig0LIAI5AzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOP8wAkkfWAI9AzUOPQM17j0DNKI8/ + zQKPP80AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPP8wAjj/LAY8/zCaPQM2Cj0DN3I9Azf+PQM3hj0DNToQ2wQCOP8wAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8/zQCORMsAj0DNSI9A + zd6PQM3/j0DN3o9AzYWPP80ojj7MAo8/zQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjz/NAI8+zAGPQM0mj0DNgo9AzdyPQM3+j0DN/49Azf+PQM3/j0DN449AzU+QPcsAjz/NAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjz/NAI9J + zwCPQM1Jj0DN349Azf+PQM3/j0DN/49Azf6PQM3ej0DNhY8/zSiPPswCjz/MAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI8/zACOPswCjz/NJ49AzYOPQM3dj0DN/o9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zeSPQM1QijbKAI4/zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOP8wAk0XXAI9AzUqPQM3gj0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/o9Azd+PQM2Gjz/NKY8/ + zAKPP80AAAAAAAAAAACPP8wAjj7MAo9AzSqPQM2Fj0DN3o9Azf6PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3kjz/NT4w6xgCOP8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI8/zQCTS84Ajz/NSo9AzeCPQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3+j0DN349AzYiPP80sjj/NA44/zQCPQM0Xj0DNhI9AzeGPQM3+j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN449AzVCQLsMAjz/MAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjj/NAJJB0ACPQM1Kj0DN4I9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf6PQM3jj0DNiY8/zRqPQM1nj0DN+o9Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49AzeOPP81PhzjFAI4/ + zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQM0Ak0HLAI9AzUmPQM3gj0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/I8/zXOPQM11j0DN/Y9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3jj0DNT4c/wwCOP8wAAAAAAAAAAAAAAAAAAAAAAI8/zQCNSs4Aj0DNSo9AzeCPQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/48/ + zX+PQM11j0DN/Y9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN449AzVCNOM0Ajj/NAAAAAAAAAAAAjj/MAJdJ3gCPP81Kj0DN4I9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/o8/zX6PQM10j0DN/Y9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49AzeSPQM1Si0HNAY5AzQCPP80AkDjLAI9A + zU2PQM3hj0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/o8/zX2PQM1zj0DN/Y9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3mjz/NVY07 + zwGRRsoAjz/NT49AzeOPQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/o8/zX2PQMtzj0DL/Y9Ay/+PQMv/j0DL/49A + y/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49A + y/+PQMv/j0DL349AyymPQMslj0DL2o9Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49A + y/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/o9Ay32RQ8ZykUPG/ZFD + xv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FD + xv+RQ8b/kUPG/5FDxv+RQ8b/kUPG+5FDxk2RQ8ZGkUPG+JFDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FD + xv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/pFD + xn2URsBylEbA/ZRGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RG + wP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/JRGwFCURsBJlEbA+ZRGwP+URsD/lEbA/5RG + wP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RG + wP+URsD/lEbA/pRGwH2XSbhyl0m4/ZdJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJ + uP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4+5dJuE6XSbhGl0m4+ZdJ + uP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJ + uP+XSbj/l0m4/5dJuP+XSbj/l0m4/pdJuH2aS69ymkyv/ZpMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pM + r/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv+5pM + r02aTK9Fmkyv+JpMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pM + r/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/ppMr32dTqVynU6l/Z1Opf+dTqX/nU6l/51O + pf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51O + pf+dTqX/nU6l+51OpU2dTqVEnU6l+J1Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51O + pf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/p1OpX2hUJtyoVCb/aFQ + m/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQm+uhUJzHoVCb/aFQm/+hUJv/oVCb/6FQ + m/+hUJv/oVCb/6FQm/+hUJv/oVCb+6FQm02hUJtFoVCb+KFQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQ + m/+hUJv/oVCb/qFQnMihUJvpoVCb/6FQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/qFQ + m32lUpBypVKQ/aVSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VSkNqkUpI3pFKRraVS + kP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ+6VSkE2lUpBFpVKQ+KVSkP+lUpD/pVKQ/6VS + kP+lUpD/pVKQ/6VSkP+lUpD/pFKRsqRSkzalUpDVpVKQ/6VSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VS + kP+lUpD/pVKQ/qVSkH6oU4VzqFOF/ahThf+oU4X/qFOF/6hThf+oU4X/qFOF/6hThf+oU4X/qFOF/6hT + hdupU4QaplOKGahThq+oU4X/qFOF/6hThf+oU4X/qFOF/6hThf+oU4X/qFOF+6hThU6oU4VHqFOF+ahT + hf+oU4X/qFOF/6hThf+oU4X/qFOF/6hThf+oU4a0p1OKHalThBeoU4XXqFOF/6hThf+oU4X/qFOF/6hT + hf+oU4X/qFOF/6hThf+oU4X/qFOF/6hThX6sVHlzrFR5/axUef+sVHn/rFR5/6xUef+sVHn/rFR5/6xU + ef+sVHn/rFR5/6xUedqsVHkbq1R7AKpUfhusVHuwrFR5/6xUef+sVHn/rFR5/6xUef+sVHn/rFR5+6xU + eU+sVHlIrFR5+axUef+sVHn/rFR5/6xUef+sVHn/rFR5/6xUerWqVH4eq1R7AKxUeRisVHnWrFR5/6xU + ef+sVHn/rFR5/6xUef+sVHn/rFR5/6xUef+sVHn/rFR5/6xUeX+wVW1zsFVt/bBVbf+wVW3/sFVt/7BV + bf+wVW3/sFVt/7BVbf+wVW3/sFVt/7BVbdqwVW0bsFVtAK5VcQCuVHIcr1VvsrBVbf+wVW3/sFVt/7BV + bf+wVW3/sFVt+7BVbVCwVW1IsFVt+bBVbf+wVW3/sFVt/7BVbf+wVW3/r1Vutq5Uch+uVXEAsFVtALBV + bRewVW3WsFVt/7BVbf+wVW3/sFVt/7BVbf+wVW3/sFVt/7BVbf+wVW3/sFVt/7BVbX+zVGF0s1Rh/bNU + Yf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NUYdqzVGEbs1RhALJUZACyVWUAslVmHbNU + YrOzVGD/s1Rh/7NUYf+zVGH/s1Rh+7NUYVCzVGFJs1Rh+bNUYf+zVGH/s1Rh/7NUYP+zVGK3slVmILJV + ZQCyVGYAs1RhALNUYRezVGHVs1Rh/7NUYf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NU + YX+3VFR0t1RU/bdUVP+3VFT/t1RU/7dUVP+3VFT/t1RU/7dUVP+3VFT/t1RU/7dUVNq2VFQbtlRUAAAA + AAC5UE8AtVRZALVUWh62VFazt1RU/7dUVP+3VFT/t1RU+7dUVE+2VFRIt1RU+bdUVP+3VFT/t1RU/7ZU + Vri1VFohtVRZALZSVgAAAAAAtlNUALZTVBe2VFTVt1RU/7dUVP+3VFT/t1RU/7dUVP+3VFT/t1RU/7dU + VP+3VFT/t1RU/7ZUVIC6U0h0ulNI/bpTSP+6U0j/ulNI/7pTSP+6U0j/ulNI/7pTSP+6U0j/ulNI/7pT + SNq6U0gbulNIAAAAAAAAAAAAuFNPALlTTAC4U00euVNJs7pTSP+6U0j/uVNI+7lTSE65U0hGuVNI+bpT + SP+6U0j/uVNJt7hTTSG4U00AvlQ5AAAAAAAAAAAAuVNIALlTSBe5U0jVulNI/7pTSP+6U0j/ulNI/7pT + SP+6U0j/ulNI/7pTSP+6U0j/ulNI/7pTSIC8Ujt0vFI7/bxSO/+8Ujv/vFI7/7xSO/+8Ujv/vFI7/7xS + O/+8Ujv/vFI7/7xSO9q8UjsbvFI7AAAAAAAAAAAAAAAAALtRPwC7UkAAu1JBHbxSPbC8Ujv/vFI7+7xS + O0y8UjtEvFI7+LxSO/+8Ujy1u1JBILtSPwC7UkEAAAAAAAAAAAAAAAAAvFI7ALxSOxe8UjvVvFI7/7xS + O/+8Ujv/vFI7/7xSO/+8Ujv/vFI7/7xSO/+8Ujv/vFI7/7xSO4C/US11v1Et/b9RLf+/US3/v1Et/79R + Lf+/US3/v1Et/79RLf+/US3/v1Et/79RLdu/US0bv1EtAAAAAAAAAAAAAAAAAAAAAADAUBwAvlEzAL5R + NBq+US+rv1Et+L9RLUm/US1Cv1Et9r5RL7C+UTMdvlEzAMBOKwAAAAAAAAAAAAAAAAAAAAAAvlEtAL5R + LRe/US3Vv1Et/79RLf+/US3/v1Et/79RLf+/US3/v1Et/79RLf+/US3/v1Et/79RLYDBUB51wVAe/cFQ + Hv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQHtvBUB4cwVAeAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwU8kAMBQJQDAUCYYwFAhm8FQH0DBUB86wVAhncBQJhvAUCUAwFAlAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwVAeAMFPHhfBUB7WwVAe/8FQHv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQ + HoDCTw51wk8O/cNPDv/DTw7/w08O/8NPDv/DTw7/w08O/8NPDv/DTw7/w08O/8JPDtzCTw4cwk8OAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMM9AADCTxcAwk8WD8JPFg7CTxYNwk8WEMJPFwDETwUAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAwk8OAMJPDhjCTw7Ww08O/8NPDv/DTw7/w08O/8NPDv/DTw7/w08O/8NP + Dv/DTw7/w08O/8JPDoDDTwh0w08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + CdzDTggdw04IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwk8IAMJPCBjDTwnXw08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCIDDTwl0w08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/8NPCdzDTwgdw08IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw04IAMNOCBnDTwnXw08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCX/DTwl0w08J/cNPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCd3DTwgdw08IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw08IAMNP + CBnDTwnYw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCX/DTwlzw08J/cNP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCdzDTwgdw08IAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAw08IAMNPCBnDTwnYw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/sNP + CX7DTwlzw08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCdXDTgkXw04JAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAwk8JAMJPCRTDTwnQw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/sNPCX3DTwlyw08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn9w08J1cNP + CWjDTggEw04IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwk8IAMFOCAPDTwljw08J08NPCfzDTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/sNPCXvDTwlxw08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/cNP + CdPDTwl0w04JHsNPBwHDTwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJPCAC/TQcAw08JHMNP + CXHDTwnRw08J/MNPCf/DTwn/w08J/8NPCf/DTwn/w08J/sNPCXrDTwlww08J/cNPCf/DTwn/w08J/8NP + Cf3DTwnUw08JdMNOCR3DTQcAw04IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwk4IAMFLBwDCTwkbw08JccNPCdHDTwn8w08J/8NPCf/DTwn/w08J/sNPCXjDTwluw08J/MNP + Cf/DTwn8w08J08NPCXXDTwkewU0EAMJOBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCTgkAv00KAMNOCBzDTwlyw08J0cNPCfzDTwn/w08J/sNP + CXbDTwltw08J+cNPCdDDTwlyw04JHcFPBgDCTggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJOCQDDTgkAw08JG8NP + CW/DTwnOw08J+cNPCXXDTwlGw08JaMJPCRrATAUAwk4IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwk8IAL5QBADDTwgZw08JaMNOCUrDTQgBw00IAMNNCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDTggAw04IAMNPCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + RU5ErkJggg== + + + \ No newline at end of file diff --git a/FireWallet/MainForm.Designer.cs b/FireWallet/MainForm.Designer.cs index cf2a87a..f4461f7 100644 --- a/FireWallet/MainForm.Designer.cs +++ b/FireWallet/MainForm.Designer.cs @@ -39,6 +39,7 @@ namespace FireWallet toolStripStatusLabelNetwork = new ToolStripStatusLabel(); toolStripStatusLabelstatus = new ToolStripStatusLabel(); toolStripStatusLabelaccount = new ToolStripStatusLabel(); + toolStripStatusLabelMultisig = new ToolStripStatusLabel(); toolStripStatusLabelLedger = new ToolStripStatusLabel(); toolStripSplitButtonlogout = new ToolStripSplitButton(); toolStripDropDownButtonHelp = new ToolStripDropDownButton(); @@ -59,12 +60,14 @@ namespace FireWallet buttonaccountnew = new Button(); panelNav = new Panel(); buttonNavSettings = new Button(); + buttonMultiSign = new Button(); buttonBatch = new Button(); buttonNavDomains = new Button(); buttonNavReceive = new Button(); buttonNavSend = new Button(); buttonNavPortfolio = new Button(); panelPortfolio = new Panel(); + buttonSendAll = new Button(); buttonRedeemAll = new Button(); buttonRevealAll = new Button(); groupBoxTransactions = new GroupBox(); @@ -127,7 +130,7 @@ namespace FireWallet textBoxExAddr = new TextBox(); labelSettings4 = new Label(); textBoxExTX = new TextBox(); - buttonSendAll = new Button(); + buttonMultiSettings = new Button(); statusStripmain.SuspendLayout(); panelaccount.SuspendLayout(); groupBoxaccount.SuspendLayout(); @@ -151,7 +154,7 @@ namespace FireWallet // statusStripmain // statusStripmain.Dock = DockStyle.Top; - statusStripmain.Items.AddRange(new ToolStripItem[] { toolStripStatusLabelNetwork, toolStripStatusLabelstatus, toolStripStatusLabelaccount, toolStripStatusLabelLedger, toolStripSplitButtonlogout, toolStripDropDownButtonHelp }); + statusStripmain.Items.AddRange(new ToolStripItem[] { toolStripStatusLabelNetwork, toolStripStatusLabelstatus, toolStripStatusLabelaccount, toolStripStatusLabelMultisig, toolStripStatusLabelLedger, toolStripSplitButtonlogout, toolStripDropDownButtonHelp }); statusStripmain.Location = new Point(0, 0); statusStripmain.Name = "statusStripmain"; statusStripmain.Size = new Size(1152, 22); @@ -183,12 +186,20 @@ namespace FireWallet toolStripStatusLabelaccount.Size = new Size(55, 17); toolStripStatusLabelaccount.Text = "Account:"; // + // toolStripStatusLabelMultisig + // + toolStripStatusLabelMultisig.Margin = new Padding(50, 3, 50, 2); + toolStripStatusLabelMultisig.Name = "toolStripStatusLabelMultisig"; + toolStripStatusLabelMultisig.Size = new Size(50, 17); + toolStripStatusLabelMultisig.Text = "Multisig"; + toolStripStatusLabelMultisig.Visible = false; + // // toolStripStatusLabelLedger // toolStripStatusLabelLedger.Margin = new Padding(50, 3, 50, 2); toolStripStatusLabelLedger.Name = "toolStripStatusLabelLedger"; - toolStripStatusLabelLedger.Size = new Size(71, 17); - toolStripStatusLabelLedger.Text = "Cold Wallet:"; + toolStripStatusLabelLedger.Size = new Size(68, 17); + toolStripStatusLabelLedger.Text = "Cold Wallet"; toolStripStatusLabelLedger.Visible = false; // // toolStripSplitButtonlogout @@ -356,6 +367,8 @@ namespace FireWallet // panelNav // panelNav.Controls.Add(buttonNavSettings); + panelNav.Controls.Add(buttonMultiSettings); + panelNav.Controls.Add(buttonMultiSign); panelNav.Controls.Add(buttonBatch); panelNav.Controls.Add(buttonNavDomains); panelNav.Controls.Add(buttonNavReceive); @@ -380,6 +393,19 @@ namespace FireWallet buttonNavSettings.UseVisualStyleBackColor = true; buttonNavSettings.Click += buttonNavSettings_Click; // + // buttonMultiSign + // + buttonMultiSign.FlatStyle = FlatStyle.Flat; + buttonMultiSign.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + buttonMultiSign.Location = new Point(12, 301); + buttonMultiSign.Name = "buttonMultiSign"; + buttonMultiSign.Size = new Size(89, 30); + buttonMultiSign.TabIndex = 3; + buttonMultiSign.TabStop = false; + buttonMultiSign.Text = "Import TX"; + buttonMultiSign.UseVisualStyleBackColor = true; + buttonMultiSign.Click += buttonMultiSign_Click; + // // buttonBatch // buttonBatch.FlatStyle = FlatStyle.Flat; @@ -459,6 +485,18 @@ namespace FireWallet panelPortfolio.TabIndex = 7; panelPortfolio.Visible = false; // + // buttonSendAll + // + buttonSendAll.FlatStyle = FlatStyle.Flat; + buttonSendAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + buttonSendAll.Location = new Point(761, 12); + buttonSendAll.Name = "buttonSendAll"; + buttonSendAll.Size = new Size(106, 44); + buttonSendAll.TabIndex = 9; + buttonSendAll.Text = "Send All TXs"; + buttonSendAll.UseVisualStyleBackColor = true; + buttonSendAll.Click += buttonSendAll_Click; + // // buttonRedeemAll // buttonRedeemAll.FlatStyle = FlatStyle.Flat; @@ -1121,17 +1159,18 @@ namespace FireWallet textBoxExTX.Size = new Size(307, 29); textBoxExTX.TabIndex = 1; // - // buttonSendAll + // buttonMultiSettings // - buttonSendAll.FlatStyle = FlatStyle.Flat; - buttonSendAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - buttonSendAll.Location = new Point(761, 12); - buttonSendAll.Name = "buttonSendAll"; - buttonSendAll.Size = new Size(106, 44); - buttonSendAll.TabIndex = 9; - buttonSendAll.Text = "Send All TXs"; - buttonSendAll.UseVisualStyleBackColor = true; - buttonSendAll.Click += buttonSendAll_Click; + buttonMultiSettings.FlatStyle = FlatStyle.Flat; + buttonMultiSettings.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + buttonMultiSettings.Location = new Point(12, 466); + buttonMultiSettings.Name = "buttonMultiSettings"; + buttonMultiSettings.Size = new Size(89, 30); + buttonMultiSettings.TabIndex = 3; + buttonMultiSettings.TabStop = false; + buttonMultiSettings.Text = "Multisig"; + buttonMultiSettings.UseVisualStyleBackColor = true; + buttonMultiSettings.Click += buttonMultiSettings_Click; // // MainForm // @@ -1281,5 +1320,8 @@ namespace FireWallet private ToolStripMenuItem otherProjectsToolStripMenuItem; private Button buttonRedeemAll; private Button buttonSendAll; + private ToolStripStatusLabel toolStripStatusLabelMultisig; + private Button buttonMultiSign; + private Button buttonMultiSettings; } } \ No newline at end of file diff --git a/FireWallet/MainForm.cs b/FireWallet/MainForm.cs index e0b4def..1bd227a 100644 --- a/FireWallet/MainForm.cs +++ b/FireWallet/MainForm.cs @@ -1,17 +1,17 @@ using System.Diagnostics; -using System.Runtime.InteropServices; -using Newtonsoft.Json.Linq; -using Point = System.Drawing.Point; -using Size = System.Drawing.Size; -using QRCoder; -using System.Text.RegularExpressions; -using System.Security.Cryptography; -using System.Text; using System.Net; +using System.Net.Security; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; using DnsClient; using DnsClient.Protocol; -using System.Security.Cryptography.X509Certificates; -using System.Net.Security; +using Newtonsoft.Json.Linq; +using QRCoder; +using Point = System.Drawing.Point; +using Size = System.Drawing.Size; namespace FireWallet { @@ -37,6 +37,7 @@ namespace FireWallet // Batching variables public bool BatchMode { get; set; } public BatchForm BatchForm { get; set; } + public bool multiSig { get; set; } #endregion #region Application public MainForm() @@ -767,28 +768,59 @@ namespace FireWallet if (jObject["watchOnly"].ToString() == "True") { WatchOnly = true; - toolStripStatusLabelLedger.Text = "Cold Wallet"; toolStripStatusLabelLedger.Visible = true; + buttonAddressVerify.Visible = true; + } + else + { + WatchOnly = false; + toolStripStatusLabelLedger.Visible = false; + buttonAddressVerify.Visible = false; + } + + path = "wallet/" + Account + "/account/default"; + APIresponse = await APIGet(path, true); + if (APIresponse.Contains("Error")) + { + AddLog("Error getting default account"); + multiSig = false; + } + else + { + jObject = JObject.Parse(APIresponse); + if (jObject["n"].ToString() == "1") + { + multiSig = false; + } + else + { + multiSig = true; + } + } + + if (multiSig) + { + toolStripStatusLabelMultisig.Visible = true; + buttonMultiSettings.Visible = true; + } + else + { + toolStripStatusLabelMultisig.Visible = false; + buttonMultiSettings.Visible = false; + } + if (WatchOnly || multiSig) + { buttonRevealAll.Visible = false; buttonRedeemAll.Visible = false; buttonSendAll.Visible = false; } else { - WatchOnly = false; - toolStripStatusLabelLedger.Visible = false; buttonRevealAll.Visible = true; buttonRedeemAll.Visible = true; buttonSendAll.Visible = true; } - if (WatchOnly) - { - buttonAddressVerify.Visible = true; - } - else - { - buttonAddressVerify.Visible = false; - } + return true; } @@ -1495,6 +1527,12 @@ namespace FireWallet } #endregion #region Nav + private void buttonMultiSign_Click(object sender, EventArgs e) + { + ImportTXForm importTXForm = new ImportTXForm(this); + importTXForm.ShowDialog(); + importTXForm.Dispose(); + } private async void PortfolioPanel_Click(object sender, EventArgs e) { hidePages(); @@ -1763,7 +1801,8 @@ namespace FireWallet { labelSendingError.Show(); labelSendingError.Text = "HIP-02 lookup failed"; - } else + } + else { labelSendingHIPAddress.Text = address; labelSendingHIPAddress.Show(); @@ -1887,7 +1926,7 @@ namespace FireWallet return; } - if (!WatchOnly) + if (!WatchOnly && !multiSig) { string content = "{\"method\": \"sendtoaddress\",\"params\": [ \"" + address + "\", " + amount.ToString() + ", \"\", \"\", " + subtractFee + " ]}"; @@ -1897,7 +1936,10 @@ namespace FireWallet { AddLog("Failed:"); AddLog(APIresp.ToString()); - NotifyForm notify = new NotifyForm("Error Transaction Failed"); + JObject error = JObject.Parse(APIresp["error"].ToString()); + string ErrorMessage = error["message"].ToString(); + + NotifyForm notify = new NotifyForm("Error Transaction Failed\n" + ErrorMessage); notify.ShowDialog(); return; } @@ -1912,96 +1954,156 @@ namespace FireWallet labelSendingError.Text = ""; buttonNavPortfolio.PerformClick(); } - else // Cold wallet signing + else // Cold or multisig wallet signing { - AddLog("Sending CW " + amount.ToString() + " HNS to " + address); - - if (!Directory.Exists(dir + "hsd-ledger")) + if (multiSig) { - if (CheckNodeInstalled() == false) + if (!WatchOnly) { - AddLog("Node not installed"); - NotifyForm notify1 = new NotifyForm("Node not installed\nPlease install it to use Ledger"); - notify1.ShowDialog(); - notify1.Dispose(); - return; + string content = "{\"method\": \"createsendtoaddress\",\"params\": [ \"" + address + "\", " + + amount.ToString() + ", \"\", \"\", " + subtractFee + " ]}"; + string output = await APIPost("", true, content); + JObject APIresp = JObject.Parse(output); + if (APIresp["error"].ToString() != "") + { + AddLog("Failed:"); + AddLog(APIresp.ToString()); + JObject error = JObject.Parse(APIresp["error"].ToString()); + string ErrorMessage = error["message"].ToString(); + + NotifyForm notify = new NotifyForm("Error Transaction Failed\n" + ErrorMessage); + notify.ShowDialog(); + return; + } + JObject result = JObject.Parse(APIresp["result"].ToString()); + string hex = result["hex"].ToString(); + + content = "{\"tx\": \"" + hex + "\",\"passphrase\":\"" + Password + "\"}"; + output = await APIPost("wallet/" + Account + "/sign", true, content); + if (!output.Contains("hex")) + { + AddLog("Failed:"); + AddLog(APIresp.ToString()); + NotifyForm notify = new NotifyForm("Error Transaction Failed\nCheck the logs"); + notify.ShowDialog(); + return; + } + ExportTransaction(output); } - AddLog("Installing hsd-ledger"); - - // Try to install hsd-ledger - try + else { - NotifyForm Notifyinstall = new NotifyForm("Installing hsd-ledger\nThis may take a few minutes\nDo not close FireWallet", false); - Notifyinstall.Show(); - // Wait for the notification to show - await Task.Delay(1000); + string content = "{\"method\": \"createsendtoaddress\",\"params\": [ \"" + address + "\", " + + amount.ToString() + ", \"\", \"\", " + subtractFee + " ]}"; + string output = await APIPost("", true, content); + JObject APIresp = JObject.Parse(output); + if (APIresp["error"].ToString() != "") + { + AddLog("Failed:"); + AddLog(APIresp.ToString()); + JObject error = JObject.Parse(APIresp["error"].ToString()); + string ErrorMessage = error["message"].ToString(); - string repositoryUrl = "https://github.com/handshake-org/hsd-ledger.git"; - string destinationPath = dir + "hsd-ledger"; - CloneRepository(repositoryUrl, destinationPath); - - Notifyinstall.CloseNotification(); - Notifyinstall.Dispose(); + NotifyForm notify = new NotifyForm("Error Transaction Failed\n" + ErrorMessage); + notify.ShowDialog(); + return; + } + string signed = signRaw(output, new string[0]); + ExportTransaction(signed); } - catch (Exception ex) + + + } + else // Cold wallet non multisig + { + AddLog("Sending CW " + amount.ToString() + " HNS to " + address); + + if (!Directory.Exists(dir + "hsd-ledger")) { - NotifyForm notifyError = new NotifyForm("Error installing hsd-ledger\n" + ex.Message); - AddLog(ex.Message); + if (CheckNodeInstalled() == false) + { + AddLog("Node not installed"); + NotifyForm notify1 = new NotifyForm("Node not installed\nPlease install it to use Ledger"); + notify1.ShowDialog(); + notify1.Dispose(); + return; + } + AddLog("Installing hsd-ledger"); + + // Try to install hsd-ledger + try + { + NotifyForm Notifyinstall = new NotifyForm("Installing hsd-ledger\nThis may take a few minutes\nDo not close FireWallet", false); + Notifyinstall.Show(); + // Wait for the notification to show + await Task.Delay(1000); + + string repositoryUrl = "https://github.com/handshake-org/hsd-ledger.git"; + string destinationPath = dir + "hsd-ledger"; + CloneRepository(repositoryUrl, destinationPath); + + Notifyinstall.CloseNotification(); + Notifyinstall.Dispose(); + } + catch (Exception ex) + { + NotifyForm notifyError = new NotifyForm("Error installing hsd-ledger\n" + ex.Message); + AddLog(ex.Message); + notifyError.ShowDialog(); + notifyError.Dispose(); + return; + } + + } + + NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false); + notify.Show(); + + var proc = new Process(); + proc.StartInfo.CreateNoWindow = true; + proc.StartInfo.RedirectStandardInput = true; + proc.StartInfo.RedirectStandardOutput = true; + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.RedirectStandardError = true; + proc.StartInfo.FileName = "node.exe"; + proc.StartInfo.Arguments = dir + "hsd-ledger/bin/hsd-ledger sendtoaddress " + textBoxSendingTo.Text + + " " + textBoxSendingAmount.Text + " --api-key " + NodeSettings["Key"] + " -w " + Account; + var outputBuilder = new StringBuilder(); + + // Event handler for capturing output data + proc.OutputDataReceived += (sender, args) => + { + if (!string.IsNullOrEmpty(args.Data)) + { + outputBuilder.AppendLine(args.Data); + } + }; + + proc.Start(); + proc.BeginOutputReadLine(); + proc.WaitForExit(); + + notify.CloseNotification(); + notify.Dispose(); + + string output = outputBuilder.ToString(); + AddLog(output); + if (output.Contains("Submitted TXID")) + { + string hash = output.Substring(output.IndexOf("Submitted TXID") + 16, 64); + string link = UserSettings["explorer-tx"] + hash; + NotifyForm notifySuccess = new NotifyForm("Transaction Sent\nThis transaction could take up to 20 minutes to mine", + "Explorer", link); + notifySuccess.ShowDialog(); + textBoxSendingTo.Text = ""; + textBoxSendingAmount.Text = ""; + buttonNavPortfolio.PerformClick(); + } + else + { + NotifyForm notifyError = new NotifyForm("Error Transaction Failed\nCheck logs for more details"); notifyError.ShowDialog(); notifyError.Dispose(); - return; } - - } - - NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false); - notify.Show(); - - var proc = new Process(); - proc.StartInfo.CreateNoWindow = true; - proc.StartInfo.RedirectStandardInput = true; - proc.StartInfo.RedirectStandardOutput = true; - proc.StartInfo.UseShellExecute = false; - proc.StartInfo.RedirectStandardError = true; - proc.StartInfo.FileName = "node.exe"; - proc.StartInfo.Arguments = dir + "hsd-ledger/bin/hsd-ledger sendtoaddress " + textBoxSendingTo.Text - + " " + textBoxSendingAmount.Text + " --api-key " + NodeSettings["Key"] + " -w " + Account; - var outputBuilder = new StringBuilder(); - - // Event handler for capturing output data - proc.OutputDataReceived += (sender, args) => - { - if (!string.IsNullOrEmpty(args.Data)) - { - outputBuilder.AppendLine(args.Data); - } - }; - - proc.Start(); - proc.BeginOutputReadLine(); - proc.WaitForExit(); - - notify.CloseNotification(); - notify.Dispose(); - - string output = outputBuilder.ToString(); - AddLog(output); - if (output.Contains("Submitted TXID")) - { - string hash = output.Substring(output.IndexOf("Submitted TXID") + 16, 64); - string link = UserSettings["explorer-tx"] + hash; - NotifyForm notifySuccess = new NotifyForm("Transaction Sent\nThis transaction could take up to 20 minutes to mine", - "Explorer", link); - notifySuccess.ShowDialog(); - textBoxSendingTo.Text = ""; - textBoxSendingAmount.Text = ""; - buttonNavPortfolio.PerformClick(); - } - else - { - NotifyForm notifyError = new NotifyForm("Error Transaction Failed\nCheck logs for more details"); - notifyError.ShowDialog(); - notifyError.Dispose(); } } @@ -2014,6 +2116,7 @@ namespace FireWallet labelSendingError.Text = ex.Message; } } + public void CloneRepository(string repositoryUrl, string destinationPath) { try @@ -2446,6 +2549,7 @@ namespace FireWallet BatchMode = true; } BatchForm.AddBatch(domain, operation); + BatchForm.UpdateTheme(); } public void AddBatch(string domain, string operation, decimal bid, decimal lockup) @@ -2458,6 +2562,7 @@ namespace FireWallet BatchMode = true; } BatchForm.AddBatch(domain, operation, bid, lockup); + BatchForm.UpdateTheme(); } public void AddBatch(string domain, string operation, DNS[] updateRecords) @@ -2469,6 +2574,7 @@ namespace FireWallet BatchMode = true; } BatchForm.AddBatch(domain, operation, updateRecords); + BatchForm.UpdateTheme(); } public void AddBatch(string domain, string operation, string address) { @@ -2479,6 +2585,7 @@ namespace FireWallet BatchMode = true; } BatchForm.AddBatch(domain, operation, address); + BatchForm.UpdateTheme(); } public void FinishBatch() { @@ -2622,5 +2729,170 @@ namespace FireWallet #endregion + + #region Multi + public async Task ExportTransaction(string rawTX) + { + return await ExportTransaction(rawTX, new string[0]); + } + public async Task ExportTransaction(string rawTX, string[] domains) + { + JObject tx = JObject.Parse(rawTX); + JObject toExport = new JObject(); + toExport["version"] = 1; + toExport["tx"] = tx["hex"]; + JArray inputsParsed = new JArray(); + JArray outputsParsed = new JArray(); + JArray inputs = JArray.Parse(tx["inputs"].ToString()); + JArray outputs = JArray.Parse(tx["outputs"].ToString()); + + Dictionary hashes = new Dictionary(); + foreach (string domain in domains) + { + // sha3 hash of domain + hashes.Add(CalculateSHA3Hash(domain), domain); + } + + foreach (JObject input in inputs) + { + JObject coin = JObject.Parse(input["coin"].ToString()); + JObject covenant = JObject.Parse(coin["covenant"].ToString()); + string type = covenant["type"].ToString(); + JObject data = new JObject(); + if (type == "0") + { + inputsParsed.Add(data); + } + else + { + AddLog("Not supported yet"); + return "Error"; + } + } + foreach (JObject output in outputs) + { + JObject covenant = JObject.Parse(output["covenant"].ToString()); + string type = covenant["type"].ToString(); + JObject data = new JObject(); + if (type == "0") + { + outputsParsed.Add(data); + } + else + { + string hash = covenant["items"][0].ToString(); + if (hashes.ContainsKey(hash)) + { + data["name"] = hashes[hash]; + } + else + { + AddLog("Cannot find name for hash " + hash); + return "Error"; + } + + //data["name"]; + outputsParsed.Add(data); + } + } + JObject metadata = new JObject(); + metadata["inputs"] = inputsParsed; + metadata["outputs"] = outputsParsed; + toExport["metadata"] = metadata; + + SaveFileDialog saveFileDialog = new SaveFileDialog + { + Filter = "JSON file (*.json)|*.json", + Title = "Save transaction as JSON" + }; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + StreamWriter sw = new StreamWriter(saveFileDialog.FileName); + sw.Write(toExport.ToString()); + sw.Dispose(); + return toExport.ToString(); + } + else + { + return "Error"; + } + } + public string signRaw(string tx, string[] domains) + { + string domainslist = string.Join(",", domains.Select(domain => "\\\"" + domain + "\\\"")); + NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false); + notify.Show(); + + var proc = new Process(); + proc.StartInfo.CreateNoWindow = true; + proc.StartInfo.RedirectStandardInput = true; + proc.StartInfo.RedirectStandardOutput = true; + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.RedirectStandardError = true; + proc.StartInfo.FileName = "node.exe"; + proc.StartInfo.WorkingDirectory = dir + "hsd-ledger/bin/"; + string args = "hsd-ledger/bin/hsd-ledger signraw \"\"" + tx.Replace("\"", "\\\"").Trim() + "\"\" [" + domainslist + "] --api-key " + NodeSettings["Key"] + " -w " + Account; + AddLog(args); + + proc.StartInfo.Arguments = dir + args; + var outputBuilder = new StringBuilder(); + + // Event handler for capturing output data + proc.OutputDataReceived += (sender, args) => + { + if (!string.IsNullOrEmpty(args.Data)) + { + outputBuilder.AppendLine(args.Data); + } + }; + + proc.Start(); + proc.BeginOutputReadLine(); + proc.WaitForExit(); + + notify.CloseNotification(); + notify.Dispose(); + + string output = outputBuilder.ToString(); + AddLog(output); + if (output.Length > 2) + { + // Signed + return output; + } + else + { + AddLog(args); + AddLog(proc.StandardError.ReadToEnd()); + NotifyForm notifyError = new NotifyForm("Error sign Failed\nCheck logs for more details"); + notifyError.ShowDialog(); + notifyError.Dispose(); + return "Error"; + } + } + static string CalculateSHA3Hash(string input) + { + var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(256); + + // Choose correct encoding based on your usecase + byte[] inputBytes = Encoding.UTF8.GetBytes(input); + + hashAlgorithm.BlockUpdate(inputBytes, 0, inputBytes.Length); + + byte[] result = new byte[256 / 8]; + hashAlgorithm.DoFinal(result, 0); + + string hashString = BitConverter.ToString(result); + hashString = hashString.Replace("-", "").ToLowerInvariant(); + return hashString; + } + private void buttonMultiSettings_Click(object sender, EventArgs e) + { + MultisigSettingsForm multisigSettingsForm = new MultisigSettingsForm(this); + multisigSettingsForm.Show(); + } + #endregion + + } } \ No newline at end of file diff --git a/FireWallet/MultisigSettingsForm.Designer.cs b/FireWallet/MultisigSettingsForm.Designer.cs new file mode 100644 index 0000000..6842c55 --- /dev/null +++ b/FireWallet/MultisigSettingsForm.Designer.cs @@ -0,0 +1,141 @@ +namespace FireWallet +{ + partial class MultisigSettingsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MultisigSettingsForm)); + groupBoxSigners = new GroupBox(); + panelSigners = new Panel(); + labelSigners = new Label(); + groupBoxAddSig = new GroupBox(); + buttoAddSigner = new Button(); + textBoxAddSig = new TextBox(); + labelAddXpub = new Label(); + groupBoxSigners.SuspendLayout(); + groupBoxAddSig.SuspendLayout(); + SuspendLayout(); + // + // groupBoxSigners + // + groupBoxSigners.Controls.Add(panelSigners); + groupBoxSigners.Location = new Point(0, 0); + groupBoxSigners.Name = "groupBoxSigners"; + groupBoxSigners.Size = new Size(418, 463); + groupBoxSigners.TabIndex = 0; + groupBoxSigners.TabStop = false; + groupBoxSigners.Text = "Signers"; + // + // panelSigners + // + panelSigners.Dock = DockStyle.Fill; + panelSigners.Location = new Point(3, 19); + panelSigners.Name = "panelSigners"; + panelSigners.Size = new Size(412, 441); + panelSigners.TabIndex = 0; + // + // labelSigners + // + labelSigners.AutoSize = true; + labelSigners.Location = new Point(424, 9); + labelSigners.Name = "labelSigners"; + labelSigners.Size = new Size(48, 15); + labelSigners.TabIndex = 1; + labelSigners.Text = "Signers:"; + // + // groupBoxAddSig + // + groupBoxAddSig.Controls.Add(buttoAddSigner); + groupBoxAddSig.Controls.Add(textBoxAddSig); + groupBoxAddSig.Controls.Add(labelAddXpub); + groupBoxAddSig.Location = new Point(421, 255); + groupBoxAddSig.Name = "groupBoxAddSig"; + groupBoxAddSig.Size = new Size(381, 208); + groupBoxAddSig.TabIndex = 2; + groupBoxAddSig.TabStop = false; + groupBoxAddSig.Text = "Add Signer"; + // + // buttoAddSigner + // + buttoAddSigner.FlatStyle = FlatStyle.Flat; + buttoAddSigner.Location = new Point(6, 45); + buttoAddSigner.Name = "buttoAddSigner"; + buttoAddSigner.Size = new Size(75, 23); + buttoAddSigner.TabIndex = 2; + buttoAddSigner.Text = "Add"; + buttoAddSigner.UseVisualStyleBackColor = true; + buttoAddSigner.Click += buttoAddSigner_Click; + // + // textBoxAddSig + // + textBoxAddSig.Location = new Point(51, 16); + textBoxAddSig.Name = "textBoxAddSig"; + textBoxAddSig.Size = new Size(324, 23); + textBoxAddSig.TabIndex = 1; + textBoxAddSig.KeyDown += textBoxAddSig_KeyDown; + // + // labelAddXpub + // + labelAddXpub.AutoSize = true; + labelAddXpub.Location = new Point(6, 19); + labelAddXpub.Name = "labelAddXpub"; + labelAddXpub.Size = new Size(39, 15); + labelAddXpub.TabIndex = 0; + labelAddXpub.Text = "XPUB:"; + // + // MultisigSettingsForm + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(814, 475); + Controls.Add(groupBoxAddSig); + Controls.Add(labelSigners); + Controls.Add(groupBoxSigners); + FormBorderStyle = FormBorderStyle.Fixed3D; + Icon = (Icon)resources.GetObject("$this.Icon"); + MaximizeBox = false; + Name = "MultisigSettingsForm"; + Text = "Multisig Settings"; + Load += MultisigSettingsForm_Load; + groupBoxSigners.ResumeLayout(false); + groupBoxAddSig.ResumeLayout(false); + groupBoxAddSig.PerformLayout(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private GroupBox groupBoxSigners; + private Label labelSigners; + private Panel panelSigners; + private GroupBox groupBoxAddSig; + private Button buttoAddSigner; + private TextBox textBoxAddSig; + private Label labelAddXpub; + } +} \ No newline at end of file diff --git a/FireWallet/MultisigSettingsForm.cs b/FireWallet/MultisigSettingsForm.cs new file mode 100644 index 0000000..982387c --- /dev/null +++ b/FireWallet/MultisigSettingsForm.cs @@ -0,0 +1,216 @@ +using Newtonsoft.Json.Linq; + +namespace FireWallet +{ + public partial class MultisigSettingsForm : Form + { + MainForm mainForm; + int n; + int m; + int current; + string OwnKey; + public MultisigSettingsForm(MainForm mainForm) + { + InitializeComponent(); + this.mainForm = mainForm; + this.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]); + this.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]); + foreach (Control c in Controls) + { + mainForm.ThemeControl(c); + } + } + + private void MultisigSettingsForm_Load(object sender, EventArgs e) + { + UpdateInfo(); + } + private async void UpdateInfo() + { + // Get multisig info + string infoResp = await mainForm.APIGet("wallet/" + mainForm.Account + "/account/default", true); + mainForm.AddLog(infoResp); + + if (infoResp == "Error") + { + NotifyForm notifyForm = new NotifyForm("Error getting multisig info"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + this.Close(); + } + JObject info = JObject.Parse(infoResp); + n = int.Parse(info["n"].ToString()); + m = int.Parse(info["m"].ToString()); + labelSigners.Text = "Signers: " + m + "/" + n; + + panelSigners.Controls.Clear(); + Panel selfInfo = new Panel(); + selfInfo.Width = panelSigners.Width - SystemInformation.VerticalScrollBarWidth; + selfInfo.Height = 50; + selfInfo.Location = new Point(0, 0); + selfInfo.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]); + selfInfo.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]); + selfInfo.BorderStyle = BorderStyle.FixedSingle; + + Label selfLabel = new Label(); + selfLabel.Text = "Own Key"; + selfLabel.Location = new Point(10, 10); + selfLabel.AutoSize = true; + selfInfo.Controls.Add(selfLabel); + + Label pubKey = new Label(); + OwnKey = info["accountKey"].ToString(); + string pukKeyShort = info["accountKey"].ToString().Substring(0, 10) + "..." + info["accountKey"].ToString().Substring(info["accountKey"].ToString().Length - 10); + + pubKey.Text = pukKeyShort; + pubKey.Location = new Point(10, 30); + pubKey.AutoSize = true; + selfInfo.Controls.Add(pubKey); + + Button copyPubKey = new Button(); + copyPubKey.Text = "Copy"; + copyPubKey.AutoSize = true; + copyPubKey.FlatStyle = FlatStyle.Flat; + copyPubKey.Location = new Point(selfInfo.Width - copyPubKey.Width - 10, 10); + copyPubKey.Click += (s, e) => + { + Clipboard.SetText(OwnKey); + }; + selfInfo.Controls.Add(copyPubKey); + panelSigners.Controls.Add(selfInfo); + + // Get signers + int y = 50; + JArray signers = JArray.Parse(info["keys"].ToString()); + current = signers.Count; + foreach (string sig in signers) + { + Panel signerInfo = new Panel(); + signerInfo.Width = panelSigners.Width - SystemInformation.VerticalScrollBarWidth; + signerInfo.Height = 50; + signerInfo.Location = new Point(0, y); + signerInfo.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]); + signerInfo.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]); + signerInfo.BorderStyle = BorderStyle.FixedSingle; + + Label signerLabel = new Label(); + signerLabel.Text = "Signer"; + signerLabel.Location = new Point(10, 10); + signerLabel.AutoSize = true; + signerInfo.Controls.Add(signerLabel); + + Label signerKey = new Label(); + string signerKeyShort = sig.Substring(0, 10) + "..." + sig.Substring(sig.Length - 10); + signerKey.Text = signerKeyShort; + signerKey.Location = new Point(10, 30); + signerKey.AutoSize = true; + signerInfo.Controls.Add(signerKey); + + Button DelSignerKey = new Button(); + DelSignerKey.Text = "Remove"; + DelSignerKey.AutoSize = true; + DelSignerKey.FlatStyle = FlatStyle.Flat; + DelSignerKey.Location = new Point(signerInfo.Width - DelSignerKey.Width - 10, 10); + DelSignerKey.Click += (s, e) => + { + RemoveSig(sig); + }; + signerInfo.Controls.Add(DelSignerKey); + panelSigners.Controls.Add(signerInfo); + y += 50; + } + + + } + private async Task RemoveSig(string sig) + { + string path = "wallet/" + mainForm.Account + "/shared-key"; + string content = "{\"accountKey\": \"" + sig + "\",\"account\":\"default\"}"; + string resp = await APIPut(path, true, content); + mainForm.AddLog(resp); + UpdateInfo(); + + } + private async Task AddSigAsync(string sig) + { + string path = "wallet/" + mainForm.Account + "/shared-key"; + string content = "{\"accountKey\": \"" + sig + "\",\"account\":\"default\"}"; + string resp = await APIPut(path, true, content); + mainForm.AddLog(resp); + UpdateInfo(); + } + + private async void buttoAddSigner_Click(object sender, EventArgs e) + { + if (textBoxAddSig.Text.Length < 5) + { + NotifyForm notifyForm = new NotifyForm("You need to add a XPUB key"); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + return; + } + + await AddSigAsync(textBoxAddSig.Text); + + textBoxAddSig.Text = ""; + } + + HttpClient httpClient = new HttpClient(); + /// + /// Put to HSD API + /// + /// Path to put to + /// Whether to use port 12039 + /// Content to put + /// + public async Task APIPut(string path, bool wallet, string content) + { + if (content == "{\"passphrase\": \"\",\"timeout\": 60}") + { + return ""; + } + string key = mainForm.NodeSettings["Key"]; + string ip = mainForm.NodeSettings["IP"]; + string port = "1203"; + if (mainForm.HSDNetwork == 1) + { + port = "1303"; + } + if (wallet) port = port + "9"; + else port = port + "7"; + + HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Put, "http://" + ip + ":" + port + "/" + path); + req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("x:" + key))); + req.Content = new StringContent(content); + // Send request + + + try + { + HttpResponseMessage resp = await httpClient.SendAsync(req); + if (!resp.IsSuccessStatusCode) + { + mainForm.AddLog("Post Error: " + resp.StatusCode); + mainForm.AddLog(await resp.Content.ReadAsStringAsync()); + return "Error"; + } + return await resp.Content.ReadAsStringAsync(); + + } + catch (Exception ex) + { + mainForm.AddLog("Post Error: " + ex.Message); + return "Error"; + } + } + + private void textBoxAddSig_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + buttoAddSigner_Click(sender, e); + e.SuppressKeyPress = true; + } + } + } +} diff --git a/FireWallet/MultisigSettingsForm.resx b/FireWallet/MultisigSettingsForm.resx new file mode 100644 index 0000000..0464da4 --- /dev/null +++ b/FireWallet/MultisigSettingsForm.resx @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA + IACoJQAA7h4AAAAAAAABACAAfScAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI8/zACPQM0Aj0DNEo9AzVePQM02j0DNAI9AzQAAAAAAAAAAAI8/zQCPQM0Aj0DNNI9A + zViPQM0Sj0DNAI8/zACPQM0Uj0DNXY9AzcOPQM37j0DN1o9AzTuPQM0Ajz/NAI4/zACPQM0Aj0DNOY9A + zdWPQM37j0DNxI9AzV6PQM0Vj0DNso9AzfqPQM3/j0DN/49Azf+PQM3Wj0DNO49AzQCPQM0Aj0DNOY9A + zdSPQM3/j0DN/49Azf+PQM36j0DNtY9AzdmPQM3/j0DN/49Azf+PQM3/j0DN/49AzdaPQM05j0DNN49A + zdWPQM3/j0DN/49Azf+PQM3/j0DN/49AzdyRQ8XYkUPF/5FDxf+RQ8X/kUPF/5FDxf+RQ8X/kkPFsZJD + xa+RQ8X/kUPF/5FDxf+RQ8X/kUPF/5FDxf+RQ8Xbmkuu2JpLrv+aS67/mkuv/ppLrv6aS67/mkuu/5pL + r76aS6+9mkuu/5pLrv+aS67+mkuv/ppLrv+aS67/mkuu26VSkNilUpD/pVKQ/6RSkOajUZWrpVKQ+aVS + kP+lUpC+pVKQvKVSkP+lUpD6o1GVq6RSkOWlUpD/pVKQ/6VSkNuwVG3YsFRt/7BUbf+wVG3drlRzKq5U + c4+wVG3/sFRtv7BUbb6wVG3/rlRzka5UcymwVG3csFRt/7BUbf+wVG3cuVNI2blTSP+5U0j/uVNI3rlT + Rxy0VWELuFNOlblTSLq5U0i5uFNOlrRVYAy5U0cbuVNI3blTSP+5U0j/uVNI3MFQHtnBUB7/wVAe/8FQ + Ht/AUB4ewFAkAL5RMxC/USxQv1EsUL5RMxDAUCUAwFAeHMFQHt3BUB7/wVAe/8FQHtzDTwnZw08J/8NP + Cf/DTwnfw08JHsNPCQDETgAAx0wAAcdNAAHFTQAAw08JAMNPCR3DTwnew08J/8NPCf/DTwncw08J2MNP + Cf/DTwn/w08Jw8NPCRXDTwkAAAAAAAAAAAAAAAAAAAAAAMNPCQDDTwkUw08JwcNPCf/DTwn/w08J28NP + CdbDTwnbw08JfMNPCSHDTggAw08JAAAAAAAAAAAAAAAAAAAAAADCTwkAwU4HAMNPCSDDTwl7w08J28NP + CdjDTwlVw08JI8NOCAHDTwkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDTwgAwk4IAcNP + CSLDTwlWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AADH4wAAA8AAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEIAAABmAAAAfg + AAAP8AAAH/gAAP//AAAoAAAAGAAAADAAAAABACAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8/zACPP8wDjz/MAo8/ + zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8/zQCPP80Cjz/NA48/zQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQM0Ajz/NBY9AzTePQM2Wj0DNYo4/zAOPP80AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj0DNAI8/zQKPQM1gj0DNl49AzTmPP80Fjz/NAAAAAAAAAAAAjz/NAI8/zQWPQM04j0DNm49A + zeuPQM3/j0DN749AzWeOP8wDjz/NAAAAAAAAAAAAAAAAAAAAAACPP80Ajz/MAo9AzWSPQM3uj0DN/49A + zeuPQM2dj0DNOY8/zQWPQM0Aj0DNN49AzZyPQM3rj0DN/49Azf+PQM3/j0DN/49Aze+PQM1njz/MA48/ + zQAAAAAAAAAAAI9AzQCOP8wCj0DNZI9Aze6PQM3/j0DN/49Azf+PQM3/j0DN7I9AzZ6PQM05j0DNuY9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3vj0DNZo4/zAOPQMwAjz/NAI8/zQKPQM1jj0DN7o9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM2+j0DNwY9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN749AzWeOP84Djj7OAo9AzWWPQM3uj0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3Gj0DMwY9AzP+PQMz/j0DM/49AzP+PQMz/j0DM/49AzP+PQMz/j0DM/49AzPCPQMtZj0DLVo9A + zO+PQMz/j0DM/49AzP+PQMz/j0DM/49AzP+PQMz/j0DM/49AzP+PQMzFkkTDwJJEw/+SRMP/kkTD/5JE + w/+SRMP/kkTD/5JEw/+SRMP/kkTD/5JEw/+SRMOekkTDm5JEw/+SRMP/kkTD/5JEw/+SRMP/kkTD/5JE + w/+SRMP/kkTD/5JEw/+SRMPFmEqzwJhKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hK + s/+YSrOfmEqznJhKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hKs/+YSrP/mEqz/5hKs/+YSrPFn0+gwJ9P + oP+fT6D/n0+g/59PoP+fT6D2n0+h7J9PoP+fT6D/n0+g/59PoP+fT6Cfn0+gm59PoP+fT6D/n0+g/59P + oP+fT6Hsn0+g9p9PoP+fT6D/n0+g/59PoP+fT6DGp1OKwadTiv+nU4r/p1OK/6dTiv+nU4rdpVKPYqZT + jNynU4r/p1OK/6dTiv+nU4qfp1OKnKdTiv+nU4r/p1OK/6ZTjN6lUo9jp1OK26dTiv+nU4r/p1OK/6dT + iv+nU4rGrlRzwa5Uc/+uVHP/rlRz/65Uc/+uVHPdrlRzHKxUe0StVHTfrlRz/65Uc/+uVHOgrlRzna5U + c/+uVHP/rlR04KxUe0auVHMarlRz265Uc/+uVHP/rlRz/65Uc/+uVHPGtVRawbVUWv+1VFr/tVRa/7VU + Wv+1VFrdtVRaHLZTVgCzVWJHtFRc37VUWv+1VFqhtVRanbVUWv+0VFzhs1RiSbdTVAC1VFoatVRa27VU + Wv+1VFr/tVRa/7VUWv+1VFrHu1JBwbtSQf+7UkH/u1JB/7tSQf+7UkHdu1JBHbtSQgDAUikAuVNKR7tT + Q+K7UkGgu1JBnbtTQ+S5U0lJw1AYALtSQgC7UkEau1JB27tSQf+7UkH/u1JB/7tSQf+7UkHHwFAlwcBQ + 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 + zf+PQM38j0DNl48/zA+PP80AAAAAAAAAAAAAAAAAAAAAAI9AzQCPQM0Oj0DNk49AzfuPQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/Y9AzdWPQM1ej0DNp49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM38j0DNl48/zA+PQM0AAAAAAAAAAACPQM0Aj0DNDo9AzZOPQM37j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Aza6PQM2oj0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM38j0DNl48/zRCPP80Aj0DNAI8/zQ+PQM2Uj0DN+49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DNr49AzaePQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM38j0DNmo4/zQ+PP80Oj0DNlo9A + zfyPQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM2ukEHKp5BB + yv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr9kEHJZ5BB + yWKQQcr8kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/5BByv+QQcr/kEHK/49B + yq6TRcGnk0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NF + wf+TRcGEk0XBf5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NFwf+TRcH/k0XB/5NF + wf+TRcH/k0XBrpdJtaeXSbX/l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJ + tf+XSbX/l0m1/5dJtYKXSbZ9l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJtf+XSbX/l0m1/5dJ + tf+XSbX/l0m1/5dJtf+XSbWunE2op5xNqP+cTaj/nE2o/5xNqP+cTaj/nE2o/5xNqP+cTaf/nE2o/5xN + qP+cTaj/nE2o/5xNqP+cTaj/nE2ogZxNqHycTaj/nE2o/5xNqP+cTaj/nE2o/5xNqP+cTaf/nE2o/5xN + qP+cTaj/nE2o/5xNqP+cTaj/nE2o/5xNqK6iUZinolGY/6JRmP+iUZj/olGY/6JRmP+iUZj/olGY6KFQ + mrmiUZj8olGY/6JRmP+iUZj/olGY/6JRmP+iUZiBolGYfKJRmP+iUZj/olGY/6JRmP+iUZj/olGY/KFQ + mrqiUZjnolGY/6JRmP+iUZj/olGY/6JRmP+iUZj/olGYrqhTh6eoU4f/qFOH/6hTh/+oU4f/qFOH/6hT + h/+oU4fcplOLL6dTip6oU4f9qFOH/6hTh/+oU4f/qFOH/6hTh4KnU4d9qFOH/6hTh/+oU4f/qFOH/6hT + h/6nU4qiplOLLqhTh9moU4f/qFOH/6hTh/+oU4f/qFOH/6hTh/+oU4evrVR2p61Udv+tVHb/rVR2/61U + dv+tVHb/rVR2/61UdtytVHYbqlSAEaxUeaGtVHb9rVR2/61Udv+tVHb/rVR2g61Udn6tVHb/rVR2/61U + dv+tVHb+rFR5pKpUfxOtVHYYrVR22q1Udv+tVHb/rVR2/61Udv+tVHb/rVR2/61Udq+yVGSoslVk/7JV + ZP+yVWT/slVk/7JVZP+yVWT/slVk3LJUZByxVWcAsFVtFLJVZ6KyVWT+slVk/7JVZP+yVGSEslRkf7JV + ZP+yVWT/slVk/rJVZqawVW0VsVRnALJUZBmyVGTZslVk/7JVZP+yVWT/slVk/7JVZP+yVWT/slRkr7dU + Uai3VFH/t1RR/7dUUf+3VFH/t1RR/7dUUf+3VFHct1NRHLdTUQC1VFoAtVRaFLdUVKO3VFH+t1RR/7dU + UYO3VFF+t1RR/7dUUf63VFSmtVRaFrVUWQC3U1EAt1NRGbdUUdm3VFH/t1RR/7dUUf+3VFH/t1RR/7dU + Uf+3VFGwvFI+qLxSPv+8Uj7/vFI+/7xSPv+8Uj7/vFI+/7xSPty7Uj4cu1I+AMNRHQC6U0cAulNIFLtS + QaG8Uj7/vFI+gbxSPny8Uj7/u1JBpbpTSBa6U0cAv1E0ALtSPgC7Uj4ZvFI+2bxSPv+8Uj7/vFI+/7xS + Pv+8Uj7/vFI+/7xSPrC/UCqov1Eq/79RKv+/USr/v1Eq/79RKv+/USr/v1Aq3b9QKRy/UCkAAAAAANJE + AAC+UTMAvlE0E79RLZ+/UCp6v1Eqdr9RLaK+UTQUvlEzAMNNFwAAAAAAv1ApAL9QKRm/UCrZv1Eq/79R + Kv+/USr/v1Eq/79RKv+/USr/v1AqsMJPEqjCTxL/wk8S/8JPEv/CTxL/wk8S/8JPEv/CTxLdwk8SHcJP + EgAAAAAAAAAAAAAAAADBTx4AwU8eE8FPHCfBUBwnwVAeFMFQHgD/AAAAAAAAAAAAAADCTxIAwk8SGsJP + EtrCTxL/wk8S/8JPEv/CTxL/wk8S/8JPEv/CTxKww08JqMNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + Cd7DTwgdw08IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMNP + CADDTwgaw08J2sNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCbDDTwmow08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J3sNPCR3DTwkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAw08JAMNPCRvDTwnbw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08Jr8NPCafDTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwndw08JHMNPCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADDTwkAw08JGsNPCdrDTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwmuw08Jp8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J88NPCZrDTgkMw08JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJPCQDCTwkKw08JlsNPCfLDTwn/w08J/8NPCf/DTwn/w08J/8NP + Ca3DTwmmw08J/8NPCf/DTwn/w08J8sNPCavDTwlGw08JCcNPCQDCTgcAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw08GAMNPCQDCTwgIw08JRMNPCanDTwnxw08J/8NP + Cf/DTwn/w08JrMNPCaTDTwn/w08J8cNPCazDTwlGw04ICcNPCADDTgkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFMCQDDTwkAwk8JCMNP + CUTDTwmqw08J8cNPCf/DTwmqw08JkcNPCarDTwlFw08ICcNPCQDCTAgAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADCTwYAw08JAMNPCQjDTwlDw08JqcNPCZbDTwkXw08JCcNPCQC/SwUAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAw00FAMNPCQDDTgkIw04JGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////5/ + /j/4P/wf4B/4B4AP8AAAB+AAAAPAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA + AgAAYAYAAHAOAAB4HgAAfD4AAH/+AAB//gAAf/4AAH/+AAD//wAD///AD///8D////z//////////ygA + AAAwAAAAYAAAAAEAIAAAAAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjz7LAI8+ + ywCPPssAjz7LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkDLAI4/ywCOP8sAjkDLAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5A + zACOP8wBjz/NJY9AzXmPQM1Ig0LIAI5AzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOP8wAkkfWAI9AzUOPQM17j0DNKI8/ + zQKPP80AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPP8wAjj/LAY8/zCaPQM2Cj0DN3I9Azf+PQM3hj0DNToQ2wQCOP8wAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8/zQCORMsAj0DNSI9A + zd6PQM3/j0DN3o9AzYWPP80ojj7MAo8/zQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjz/NAI8+zAGPQM0mj0DNgo9AzdyPQM3+j0DN/49Azf+PQM3/j0DN449AzU+QPcsAjz/NAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjz/NAI9J + zwCPQM1Jj0DN349Azf+PQM3/j0DN/49Azf6PQM3ej0DNhY8/zSiPPswCjz/MAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI8/zACOPswCjz/NJ49AzYOPQM3dj0DN/o9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zeSPQM1QijbKAI4/zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOP8wAk0XXAI9AzUqPQM3gj0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/o9Azd+PQM2Gjz/NKY8/ + zAKPP80AAAAAAAAAAACPP8wAjj7MAo9AzSqPQM2Fj0DN3o9Azf6PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3kjz/NT4w6xgCOP8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI8/zQCTS84Ajz/NSo9AzeCPQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3+j0DN349AzYiPP80sjj/NA44/zQCPQM0Xj0DNhI9AzeGPQM3+j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN449AzVCQLsMAjz/MAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjj/NAJJB0ACPQM1Kj0DN4I9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf6PQM3jj0DNiY8/zRqPQM1nj0DN+o9Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49AzeOPP81PhzjFAI4/ + zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQM0Ak0HLAI9AzUmPQM3gj0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/I8/zXOPQM11j0DN/Y9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3jj0DNT4c/wwCOP8wAAAAAAAAAAAAAAAAAAAAAAI8/zQCNSs4Aj0DNSo9AzeCPQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/48/ + zX+PQM11j0DN/Y9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN449AzVCNOM0Ajj/NAAAAAAAAAAAAjj/MAJdJ3gCPP81Kj0DN4I9A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/o8/zX6PQM10j0DN/Y9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49AzeSPQM1Si0HNAY5AzQCPP80AkDjLAI9A + zU2PQM3hj0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/o8/zX2PQM1zj0DN/Y9Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3mjz/NVY07 + zwGRRsoAjz/NT49AzeOPQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/49A + zf+PQM3/j0DN/49Azf+PQM3/j0DN/49Azf+PQM3/j0DN/o8/zX2PQMtzj0DL/Y9Ay/+PQMv/j0DL/49A + y/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49A + y/+PQMv/j0DL349AyymPQMslj0DL2o9Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49A + y/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/49Ay/+PQMv/j0DL/o9Ay32RQ8ZykUPG/ZFD + xv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FD + xv+RQ8b/kUPG/5FDxv+RQ8b/kUPG+5FDxk2RQ8ZGkUPG+JFDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FD + xv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/5FDxv+RQ8b/kUPG/pFD + xn2URsBylEbA/ZRGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RG + wP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/JRGwFCURsBJlEbA+ZRGwP+URsD/lEbA/5RG + wP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RGwP+URsD/lEbA/5RG + wP+URsD/lEbA/pRGwH2XSbhyl0m4/ZdJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJ + uP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4+5dJuE6XSbhGl0m4+ZdJ + uP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJuP+XSbj/l0m4/5dJ + uP+XSbj/l0m4/5dJuP+XSbj/l0m4/pdJuH2aS69ymkyv/ZpMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pM + r/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv+5pM + r02aTK9Fmkyv+JpMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/5pM + r/+aTK//mkyv/5pMr/+aTK//mkyv/5pMr/+aTK//mkyv/ppMr32dTqVynU6l/Z1Opf+dTqX/nU6l/51O + pf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51O + pf+dTqX/nU6l+51OpU2dTqVEnU6l+J1Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51O + pf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/51Opf+dTqX/nU6l/p1OpX2hUJtyoVCb/aFQ + m/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQm+uhUJzHoVCb/aFQm/+hUJv/oVCb/6FQ + m/+hUJv/oVCb/6FQm/+hUJv/oVCb+6FQm02hUJtFoVCb+KFQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQ + m/+hUJv/oVCb/qFQnMihUJvpoVCb/6FQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/6FQm/+hUJv/oVCb/qFQ + m32lUpBypVKQ/aVSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VSkNqkUpI3pFKRraVS + kP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ+6VSkE2lUpBFpVKQ+KVSkP+lUpD/pVKQ/6VS + kP+lUpD/pVKQ/6VSkP+lUpD/pFKRsqRSkzalUpDVpVKQ/6VSkP+lUpD/pVKQ/6VSkP+lUpD/pVKQ/6VS + kP+lUpD/pVKQ/qVSkH6oU4VzqFOF/ahThf+oU4X/qFOF/6hThf+oU4X/qFOF/6hThf+oU4X/qFOF/6hT + hdupU4QaplOKGahThq+oU4X/qFOF/6hThf+oU4X/qFOF/6hThf+oU4X/qFOF+6hThU6oU4VHqFOF+ahT + hf+oU4X/qFOF/6hThf+oU4X/qFOF/6hThf+oU4a0p1OKHalThBeoU4XXqFOF/6hThf+oU4X/qFOF/6hT + hf+oU4X/qFOF/6hThf+oU4X/qFOF/6hThX6sVHlzrFR5/axUef+sVHn/rFR5/6xUef+sVHn/rFR5/6xU + ef+sVHn/rFR5/6xUedqsVHkbq1R7AKpUfhusVHuwrFR5/6xUef+sVHn/rFR5/6xUef+sVHn/rFR5+6xU + eU+sVHlIrFR5+axUef+sVHn/rFR5/6xUef+sVHn/rFR5/6xUerWqVH4eq1R7AKxUeRisVHnWrFR5/6xU + ef+sVHn/rFR5/6xUef+sVHn/rFR5/6xUef+sVHn/rFR5/6xUeX+wVW1zsFVt/bBVbf+wVW3/sFVt/7BV + bf+wVW3/sFVt/7BVbf+wVW3/sFVt/7BVbdqwVW0bsFVtAK5VcQCuVHIcr1VvsrBVbf+wVW3/sFVt/7BV + bf+wVW3/sFVt+7BVbVCwVW1IsFVt+bBVbf+wVW3/sFVt/7BVbf+wVW3/r1Vutq5Uch+uVXEAsFVtALBV + bRewVW3WsFVt/7BVbf+wVW3/sFVt/7BVbf+wVW3/sFVt/7BVbf+wVW3/sFVt/7BVbX+zVGF0s1Rh/bNU + Yf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NUYdqzVGEbs1RhALJUZACyVWUAslVmHbNU + YrOzVGD/s1Rh/7NUYf+zVGH/s1Rh+7NUYVCzVGFJs1Rh+bNUYf+zVGH/s1Rh/7NUYP+zVGK3slVmILJV + ZQCyVGYAs1RhALNUYRezVGHVs1Rh/7NUYf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NUYf+zVGH/s1Rh/7NU + YX+3VFR0t1RU/bdUVP+3VFT/t1RU/7dUVP+3VFT/t1RU/7dUVP+3VFT/t1RU/7dUVNq2VFQbtlRUAAAA + AAC5UE8AtVRZALVUWh62VFazt1RU/7dUVP+3VFT/t1RU+7dUVE+2VFRIt1RU+bdUVP+3VFT/t1RU/7ZU + Vri1VFohtVRZALZSVgAAAAAAtlNUALZTVBe2VFTVt1RU/7dUVP+3VFT/t1RU/7dUVP+3VFT/t1RU/7dU + VP+3VFT/t1RU/7ZUVIC6U0h0ulNI/bpTSP+6U0j/ulNI/7pTSP+6U0j/ulNI/7pTSP+6U0j/ulNI/7pT + SNq6U0gbulNIAAAAAAAAAAAAuFNPALlTTAC4U00euVNJs7pTSP+6U0j/uVNI+7lTSE65U0hGuVNI+bpT + SP+6U0j/uVNJt7hTTSG4U00AvlQ5AAAAAAAAAAAAuVNIALlTSBe5U0jVulNI/7pTSP+6U0j/ulNI/7pT + SP+6U0j/ulNI/7pTSP+6U0j/ulNI/7pTSIC8Ujt0vFI7/bxSO/+8Ujv/vFI7/7xSO/+8Ujv/vFI7/7xS + O/+8Ujv/vFI7/7xSO9q8UjsbvFI7AAAAAAAAAAAAAAAAALtRPwC7UkAAu1JBHbxSPbC8Ujv/vFI7+7xS + O0y8UjtEvFI7+LxSO/+8Ujy1u1JBILtSPwC7UkEAAAAAAAAAAAAAAAAAvFI7ALxSOxe8UjvVvFI7/7xS + O/+8Ujv/vFI7/7xSO/+8Ujv/vFI7/7xSO/+8Ujv/vFI7/7xSO4C/US11v1Et/b9RLf+/US3/v1Et/79R + Lf+/US3/v1Et/79RLf+/US3/v1Et/79RLdu/US0bv1EtAAAAAAAAAAAAAAAAAAAAAADAUBwAvlEzAL5R + NBq+US+rv1Et+L9RLUm/US1Cv1Et9r5RL7C+UTMdvlEzAMBOKwAAAAAAAAAAAAAAAAAAAAAAvlEtAL5R + LRe/US3Vv1Et/79RLf+/US3/v1Et/79RLf+/US3/v1Et/79RLf+/US3/v1Et/79RLYDBUB51wVAe/cFQ + Hv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQHtvBUB4cwVAeAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwU8kAMBQJQDAUCYYwFAhm8FQH0DBUB86wVAhncBQJhvAUCUAwFAlAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwVAeAMFPHhfBUB7WwVAe/8FQHv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQHv/BUB7/wVAe/8FQ + HoDCTw51wk8O/cNPDv/DTw7/w08O/8NPDv/DTw7/w08O/8NPDv/DTw7/w08O/8JPDtzCTw4cwk8OAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMM9AADCTxcAwk8WD8JPFg7CTxYNwk8WEMJPFwDETwUAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAwk8OAMJPDhjCTw7Ww08O/8NPDv/DTw7/w08O/8NPDv/DTw7/w08O/8NP + Dv/DTw7/w08O/8JPDoDDTwh0w08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + CdzDTggdw04IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwk8IAMJPCBjDTwnXw08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCIDDTwl0w08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/8NPCdzDTwgdw08IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw04IAMNOCBnDTwnXw08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCX/DTwl0w08J/cNPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCd3DTwgdw08IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw08IAMNP + CBnDTwnYw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCX/DTwlzw08J/cNP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCdzDTwgdw08IAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAw08IAMNPCBnDTwnYw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/sNP + CX7DTwlzw08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCdXDTgkXw04JAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAwk8JAMJPCRTDTwnQw08J/8NPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NP + Cf/DTwn/w08J/sNPCX3DTwlyw08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/8NPCf/DTwn9w08J1cNP + CWjDTggEw04IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwk8IAMFOCAPDTwljw08J08NPCfzDTwn/w08J/8NP + Cf/DTwn/w08J/8NPCf/DTwn/w08J/sNPCXvDTwlxw08J/cNPCf/DTwn/w08J/8NPCf/DTwn/w08J/cNP + CdPDTwl0w04JHsNPBwHDTwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJPCAC/TQcAw08JHMNP + CXHDTwnRw08J/MNPCf/DTwn/w08J/8NPCf/DTwn/w08J/sNPCXrDTwlww08J/cNPCf/DTwn/w08J/8NP + Cf3DTwnUw08JdMNOCR3DTQcAw04IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwk4IAMFLBwDCTwkbw08JccNPCdHDTwn8w08J/8NPCf/DTwn/w08J/sNPCXjDTwluw08J/MNP + Cf/DTwn8w08J08NPCXXDTwkewU0EAMJOBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCTgkAv00KAMNOCBzDTwlyw08J0cNPCfzDTwn/w08J/sNP + CXbDTwltw08J+cNPCdDDTwlyw04JHcFPBgDCTggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMJOCQDDTgkAw08JG8NP + CW/DTwnOw08J+cNPCXXDTwlGw08JaMJPCRrATAUAwk4IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAwk8IAL5QBADDTwgZw08JaMNOCUrDTQgBw00IAMNNCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDTggAw04IAMNPCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + RU5ErkJggg== + + + \ No newline at end of file diff --git a/FireWallet/NewAccountForm.Designer.cs b/FireWallet/NewAccountForm.Designer.cs index b661948..6e4089b 100644 --- a/FireWallet/NewAccountForm.Designer.cs +++ b/FireWallet/NewAccountForm.Designer.cs @@ -46,9 +46,18 @@ label2 = new Label(); groupBoxSeed = new GroupBox(); textBoxSeedPhrase = new TextBox(); + groupBoxMulti = new GroupBox(); + numericUpDownM = new NumericUpDown(); + numericUpDownN = new NumericUpDown(); + label7 = new Label(); + label6 = new Label(); + checkBoxMulti = new CheckBox(); groupBoxMode.SuspendLayout(); groupBoxNew.SuspendLayout(); groupBoxSeed.SuspendLayout(); + groupBoxMulti.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)numericUpDownM).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDownN).BeginInit(); SuspendLayout(); // // buttonNext @@ -241,11 +250,74 @@ textBoxSeedPhrase.Size = new Size(438, 288); textBoxSeedPhrase.TabIndex = 0; // + // groupBoxMulti + // + groupBoxMulti.Controls.Add(numericUpDownM); + groupBoxMulti.Controls.Add(numericUpDownN); + groupBoxMulti.Controls.Add(label7); + groupBoxMulti.Controls.Add(label6); + groupBoxMulti.Controls.Add(checkBoxMulti); + groupBoxMulti.Location = new Point(125, 22); + groupBoxMulti.Name = "groupBoxMulti"; + groupBoxMulti.Size = new Size(450, 319); + groupBoxMulti.TabIndex = 6; + groupBoxMulti.TabStop = false; + groupBoxMulti.Text = "Multisig"; + // + // numericUpDownM + // + numericUpDownM.Location = new Point(223, 91); + numericUpDownM.Maximum = new decimal(new int[] { 1000, 0, 0, 0 }); + numericUpDownM.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + numericUpDownM.Name = "numericUpDownM"; + numericUpDownM.Size = new Size(120, 23); + numericUpDownM.TabIndex = 2; + numericUpDownM.Value = new decimal(new int[] { 1, 0, 0, 0 }); + // + // numericUpDownN + // + numericUpDownN.Location = new Point(223, 55); + numericUpDownN.Maximum = new decimal(new int[] { 1000, 0, 0, 0 }); + numericUpDownN.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + numericUpDownN.Name = "numericUpDownN"; + numericUpDownN.Size = new Size(120, 23); + numericUpDownN.TabIndex = 2; + numericUpDownN.Value = new decimal(new int[] { 1, 0, 0, 0 }); + // + // label7 + // + label7.AutoSize = true; + label7.Location = new Point(6, 93); + label7.Name = "label7"; + label7.Size = new Size(211, 15); + label7.TabIndex = 1; + label7.Text = "Required Signers to send a transaction:"; + // + // label6 + // + label6.AutoSize = true; + label6.Location = new Point(141, 61); + label6.Name = "label6"; + label6.Size = new Size(76, 15); + label6.TabIndex = 1; + label6.Text = "Total Signers:"; + // + // checkBoxMulti + // + checkBoxMulti.AutoSize = true; + checkBoxMulti.Location = new Point(6, 23); + checkBoxMulti.Name = "checkBoxMulti"; + checkBoxMulti.Size = new Size(115, 19); + checkBoxMulti.TabIndex = 0; + checkBoxMulti.Text = "Create a multisig"; + checkBoxMulti.UseVisualStyleBackColor = true; + // // NewAccountForm // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(680, 430); + Controls.Add(groupBoxMulti); Controls.Add(groupBoxSeed); Controls.Add(buttonCancel); Controls.Add(buttonNext); @@ -263,6 +335,10 @@ groupBoxNew.PerformLayout(); groupBoxSeed.ResumeLayout(false); groupBoxSeed.PerformLayout(); + groupBoxMulti.ResumeLayout(false); + groupBoxMulti.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)numericUpDownM).EndInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDownN).EndInit(); ResumeLayout(false); } @@ -285,5 +361,11 @@ private Label label5; private GroupBox groupBoxSeed; private TextBox textBoxSeedPhrase; + private GroupBox groupBoxMulti; + private CheckBox checkBoxMulti; + private NumericUpDown numericUpDownM; + private NumericUpDown numericUpDownN; + private Label label7; + private Label label6; } } \ No newline at end of file diff --git a/FireWallet/NewAccountForm.cs b/FireWallet/NewAccountForm.cs index a0ea6a4..deafc09 100644 --- a/FireWallet/NewAccountForm.cs +++ b/FireWallet/NewAccountForm.cs @@ -1,17 +1,7 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.Drawing; -using System.Linq; -using System.Net.Http; -using System.Security.Principal; +using System.Diagnostics; using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Windows.Forms; -using Microsoft.VisualBasic.Devices; +using Newtonsoft.Json.Linq; namespace FireWallet { @@ -34,7 +24,7 @@ namespace FireWallet { mainForm.ThemeControl(c); } - + groupBoxMulti.Hide(); } @@ -148,53 +138,179 @@ namespace FireWallet if (page == 1) { - // Create new wallet - buttonNext.Enabled = false; - string path = "wallet/" + textBoxNewName.Text; - string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\"}"; - string response = await APIPut(path, true, content); - if (response == "Error") - { - NotifyForm notify = new NotifyForm("Error creating wallet"); - notify.ShowDialog(); - notify.Dispose(); - buttonNext.Enabled = true; - return; - } - mainForm.AddLog("Created wallet: " + textBoxNewName.Text); - NotifyForm notify2 = new NotifyForm("Created wallet: " + textBoxNewName.Text); - notify2.ShowDialog(); - notify2.Dispose(); - this.Close(); + groupBoxMulti.Show(); + page = 6; } else if (page == 2) { groupBoxSeed.Show(); - buttonNext.Text = "Import"; page = 3; } else if (page == 3) { - // Create new wallet - buttonNext.Enabled = false; - string path = "wallet/" + textBoxNewName.Text; - string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\"}"; - string response = await APIPut(path, true, content); - if (response == "Error") - { - NotifyForm notify = new NotifyForm("Error creating wallet"); - notify.ShowDialog(); - notify.Dispose(); - buttonNext.Enabled = true; - return; - } - mainForm.AddLog("Created wallet: " + textBoxNewName.Text); - NotifyForm notify2 = new NotifyForm("Imported wallet: " + textBoxNewName.Text); - notify2.ShowDialog(); - notify2.Dispose(); - this.Close(); + page = 5; + groupBoxMulti.Show(); + buttonNext.Text = "Import"; } + else if (page == 5) + { + if (!checkBoxMulti.Checked) + { + // Import wallet from seed + buttonNext.Enabled = false; + string path = "wallet/" + textBoxNewName.Text; + string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\"}"; + string response = await APIPut(path, true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error creating wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + mainForm.AddLog("Created wallet: " + textBoxNewName.Text); + NotifyForm notify2 = new NotifyForm("Imported wallet: " + textBoxNewName.Text); + notify2.ShowDialog(); + notify2.Dispose(); + this.Close(); + } + else + { + // Import wallet from seed and create multisig + buttonNext.Enabled = false; + string path = "wallet/" + textBoxNewName.Text; + string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\", \"type\":\"multisig\",\"m\":"+numericUpDownM.Value.ToString()+ ",\"n\":" +numericUpDownN.Value.ToString() + "}"; + string response = await APIPut(path, true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error creating wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + mainForm.AddLog("Created wallet: " + textBoxNewName.Text); + NotifyForm notify2 = new NotifyForm("Imported wallet: " + textBoxNewName.Text); + notify2.ShowDialog(); + notify2.Dispose(); + this.Close(); + } + } + else if (page == 6) + { + if (!checkBoxMulti.Checked) + { + // Create new wallet + buttonNext.Enabled = false; + string path = "wallet/" + textBoxNewName.Text; + string content = "{}"; + //content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\"}"; + string response = await APIPut(path, true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error creating wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + mainForm.AddLog("Created wallet: " + textBoxNewName.Text); + + // Show SEED PHRASE + path = "wallet/" + textBoxNewName.Text + "/master"; + response = await mainForm.APIGet(path, true); + JObject resp = JObject.Parse(response); + if (resp["encrypted"].ToString() == "False") + { + JObject mnemonic = JObject.Parse(resp["mnemonic"].ToString()); + string phrase = mnemonic["phrase"].ToString(); + NotifyForm notifyForm = new NotifyForm("SEED PHRASE\nSTORE THIS SOMEWHERE SECURE\n" + phrase, "Copy", phrase, true); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + } + + // Select wallet + content = "{\"method\":\"selectwallet\",\"params\":[\"" + textBoxNewName.Text + "\"]}"; + response = await mainForm.APIPost("", true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error selecting wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + + // Encrypt wallet + content = "{\"method\":\"encryptwallet\",\"params\":[\"" + textBoxNewPass1.Text + "\"]}"; + response = await mainForm.APIPost("", true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error encrypting wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + mainForm.AddLog("Encrypted wallet: " + textBoxNewName.Text); + this.Close(); + } else + { + // Create new wallet + buttonNext.Enabled = false; + string path = "wallet/" + textBoxNewName.Text; + string content = "{\"type\":\"multisig\",\"m\":"+numericUpDownM.Value.ToString()+ ",\"n\":" +numericUpDownN.Value.ToString() + "}"; + string response = await APIPut(path, true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error creating wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + path = "wallet/" + textBoxNewName.Text + "/master"; + response = await mainForm.APIGet(path, true); + JObject resp = JObject.Parse(response); + if (resp["encrypted"].ToString() == "False") + { + JObject mnemonic = JObject.Parse(resp["mnemonic"].ToString()); + string phrase = mnemonic["phrase"].ToString(); + NotifyForm notifyForm = new NotifyForm("SEED PHRASE\nSTORE THIS SOMEWHERE SECURE\n" + phrase, "Copy", phrase, true); + notifyForm.ShowDialog(); + notifyForm.Dispose(); + + } + // Select wallet + content = "{\"method\":\"selectwallet\",\"params\":[\"" + textBoxNewName.Text + "\"]}"; + response = await mainForm.APIPost("", true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error selecting wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + // Encrypt wallet + content = "{\"method\":\"encryptwallet\",\"params\":[\"" + textBoxNewPass1.Text + "\"]}"; + response = await mainForm.APIPost("", true, content); + if (response == "Error") + { + NotifyForm notify = new NotifyForm("Error encrypting wallet"); + notify.ShowDialog(); + notify.Dispose(); + buttonNext.Enabled = true; + return; + } + mainForm.AddLog("Encrypted wallet: " + textBoxNewName.Text); + this.Close(); + + } + } + else if (page == 4) { try @@ -228,7 +344,7 @@ namespace FireWallet } catch (Exception ex) { - mainForm.AddLog(ex.Message); + mainForm.AddLog(ex.Message); NotifyForm notify = new NotifyForm("Error importing wallet\n" + ex.Message); notify.ShowDialog(); notify.Dispose(); @@ -256,16 +372,17 @@ namespace FireWallet HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Put, "http://" + ip + ":" + port + "/" + path); req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("x:" + key))); req.Content = new StringContent(content); - + try { // Send request HttpResponseMessage resp = await httpClient.SendAsync(req); - + if (resp.IsSuccessStatusCode) { return await resp.Content.ReadAsStringAsync(); - } else + } + else { mainForm.AddLog("Put Error: " + await resp.Content.ReadAsStringAsync()); return "Error"; @@ -277,7 +394,7 @@ namespace FireWallet return "Error"; } - + } } } diff --git a/FireWalletSetup/FireWalletSetup.vdproj b/FireWalletSetup/FireWalletSetup.vdproj index 1c4b3bd..0b2b2d6 100644 --- a/FireWalletSetup/FireWalletSetup.vdproj +++ b/FireWalletSetup/FireWalletSetup.vdproj @@ -224,15 +224,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:FireWallet" - "ProductCode" = "8:{E636567F-DDA4-4C6E-89B0-38DC64FD5528}" - "PackageCode" = "8:{AEAF1ABA-01E0-4A71-A8CC-0D6DDA44E907}" + "ProductCode" = "8:{E904E664-B1F3-4DEB-9FB0-91BCBEE3B5A6}" + "PackageCode" = "8:{0B16637D-C5AC-41D4-9D13-D57F3A0AEF25}" "UpgradeCode" = "8:{0C86F725-6B01-4173-AA05-3F0EDF481362}" "AspNetVersion" = "8:" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:3.4" + "ProductVersion" = "8:4.0" "Manufacturer" = "8:Nathan.Woodburn/" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:https://l.woodburn.au/discord"