diff --git a/FireWallet/ExportTXForm.Designer.cs b/FireWallet/ExportTXForm.Designer.cs
new file mode 100644
index 0000000..177ed55
--- /dev/null
+++ b/FireWallet/ExportTXForm.Designer.cs
@@ -0,0 +1,143 @@
+namespace FireWallet
+{
+ partial class ExportTXForm
+ {
+ ///
+ /// 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(ExportTXForm));
+ label1 = new Label();
+ buttonExport = new Button();
+ groupBoxTXs = new GroupBox();
+ buttonRefresh = new Button();
+ numericUpDownLimit = new NumericUpDown();
+ label2 = new Label();
+ comboBoxFilter = new ComboBox();
+ ((System.ComponentModel.ISupportInitialize)numericUpDownLimit).BeginInit();
+ SuspendLayout();
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(12, 9);
+ label1.Name = "label1";
+ label1.Size = new Size(37, 15);
+ label1.TabIndex = 0;
+ label1.Text = "Limit:";
+ //
+ // buttonExport
+ //
+ buttonExport.FlatStyle = FlatStyle.Flat;
+ buttonExport.Location = new Point(694, 409);
+ buttonExport.Name = "buttonExport";
+ buttonExport.Size = new Size(94, 29);
+ buttonExport.TabIndex = 1;
+ buttonExport.Text = "Export";
+ buttonExport.UseVisualStyleBackColor = true;
+ buttonExport.Click += buttonExport_Click;
+ //
+ // groupBoxTXs
+ //
+ groupBoxTXs.Location = new Point(12, 57);
+ groupBoxTXs.Name = "groupBoxTXs";
+ groupBoxTXs.Size = new Size(553, 336);
+ groupBoxTXs.TabIndex = 2;
+ groupBoxTXs.TabStop = false;
+ groupBoxTXs.Text = "TXs";
+ //
+ // buttonRefresh
+ //
+ buttonRefresh.FlatStyle = FlatStyle.Flat;
+ buttonRefresh.Location = new Point(12, 409);
+ buttonRefresh.Name = "buttonRefresh";
+ buttonRefresh.Size = new Size(82, 29);
+ buttonRefresh.TabIndex = 3;
+ buttonRefresh.Text = "Refresh";
+ buttonRefresh.UseVisualStyleBackColor = true;
+ buttonRefresh.Click += buttonRefresh_Click;
+ //
+ // numericUpDownLimit
+ //
+ numericUpDownLimit.Location = new Point(55, 7);
+ numericUpDownLimit.Maximum = new decimal(new int[] { 100000, 0, 0, 0 });
+ numericUpDownLimit.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+ numericUpDownLimit.Name = "numericUpDownLimit";
+ numericUpDownLimit.Size = new Size(120, 23);
+ numericUpDownLimit.TabIndex = 4;
+ numericUpDownLimit.Value = new decimal(new int[] { 10, 0, 0, 0 });
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Location = new Point(209, 9);
+ label2.Name = "label2";
+ label2.Size = new Size(36, 15);
+ label2.TabIndex = 5;
+ label2.Text = "Filter:";
+ //
+ // comboBoxFilter
+ //
+ comboBoxFilter.FormattingEnabled = true;
+ comboBoxFilter.Items.AddRange(new object[] { "ALL", "NONE", "OPEN", "BID", "REVEAL", "REDEEM", "UPDATE", "TRANSFER", "FINALIZE" });
+ comboBoxFilter.Location = new Point(251, 6);
+ comboBoxFilter.Name = "comboBoxFilter";
+ comboBoxFilter.Size = new Size(121, 23);
+ comboBoxFilter.TabIndex = 6;
+ //
+ // ExportTXForm
+ //
+ AutoScaleDimensions = new SizeF(7F, 15F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(800, 450);
+ Controls.Add(comboBoxFilter);
+ Controls.Add(label2);
+ Controls.Add(numericUpDownLimit);
+ Controls.Add(buttonRefresh);
+ Controls.Add(groupBoxTXs);
+ Controls.Add(buttonExport);
+ Controls.Add(label1);
+ FormBorderStyle = FormBorderStyle.Fixed3D;
+ Icon = (Icon)resources.GetObject("$this.Icon");
+ MaximizeBox = false;
+ Name = "ExportTXForm";
+ Text = "Export TXs";
+ Load += ExportTXForm_Load;
+ ((System.ComponentModel.ISupportInitialize)numericUpDownLimit).EndInit();
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private Label label1;
+ private Button buttonExport;
+ private GroupBox groupBoxTXs;
+ private Button buttonRefresh;
+ private NumericUpDown numericUpDownLimit;
+ private Label label2;
+ private ComboBox comboBoxFilter;
+ }
+}
\ No newline at end of file
diff --git a/FireWallet/ExportTXForm.cs b/FireWallet/ExportTXForm.cs
new file mode 100644
index 0000000..7145fe6
--- /dev/null
+++ b/FireWallet/ExportTXForm.cs
@@ -0,0 +1,397 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Security.Principal;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Newtonsoft.Json.Linq;
+using Org.BouncyCastle.Crypto;
+
+namespace FireWallet
+{
+ public partial class ExportTXForm : Form
+ {
+ MainForm mainForm;
+ List TXs;
+ public ExportTXForm(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);
+ }
+ GetTXs();
+ }
+
+ private async void ExportTXForm_Load(object sender, EventArgs e)
+ {
+
+
+ }
+ private async Task GetTXs()
+ {
+ // Get TXs
+ TXs = new List();
+
+ // Check how many TX there are
+ string APIresponse = await mainForm.APIGet("wallet/" + mainForm.Account, true);
+ JObject wallet = JObject.Parse(APIresponse);
+ if (!wallet.ContainsKey("balance"))
+ {
+ mainForm.AddLog("GetInfo Error");
+ mainForm.AddLog(APIresponse);
+ return;
+ }
+ JObject balance = JObject.Parse(wallet["balance"].ToString());
+ int TotalTX = Convert.ToInt32(balance["tx"].ToString());
+ int toGet = (int)numericUpDownLimit.Value;
+
+ if (toGet > TotalTX) toGet = TotalTX;
+ int toSkip = TotalTX - toGet;
+
+ // GET TXs
+ if (mainForm.WatchOnly)
+ {
+ APIresponse = await mainForm.APIPost("", true, "{\"method\": \"listtransactions\",\"params\": [\"default\"," + toGet + "," + toSkip + ", true]}");
+ }
+ else
+ {
+ APIresponse = await mainForm.APIPost("", true, "{\"method\": \"listtransactions\",\"params\": [\"default\"," + toGet + "," + toSkip + "]}");
+ }
+
+ if (APIresponse == "Error")
+ {
+ mainForm.AddLog("GetInfo Error");
+ return;
+ }
+ JObject TXGET = JObject.Parse(APIresponse);
+
+ // Check for error
+ if (TXGET["error"].ToString() != "")
+ {
+ mainForm.AddLog("GetInfo Error");
+ mainForm.AddLog(APIresponse);
+ return;
+ }
+
+ JArray txs = JArray.Parse(TXGET["result"].ToString());
+ if (toGet > txs.Count) toGet = txs.Count; // In case there are less TXs than expected (usually happens when the get TX's fails)
+ Control[] tmpControls = new Control[toGet];
+ for (int i = 0; i < toGet; i++)
+ {
+
+ // Get last tx
+ JObject tx = JObject.Parse(await mainForm.APIGet("wallet/" + mainForm.Account + "/tx/" + txs[toGet - i - 1]["txid"].ToString(), true));
+ Transaction transaction = new Transaction();
+ transaction.Hash = tx["hash"].ToString();
+ transaction.Date = DateTime.Parse(tx["mdate"].ToString());
+ transaction.Confirmations = Convert.ToInt32(tx["confirmations"].ToString());
+
+ string hash = transaction.Hash;
+ string date = transaction.Date.ToShortDateString();
+
+
+
+
+ Panel tmpPanel = new Panel();
+ tmpPanel.Width = groupBoxTXs.Width - SystemInformation.VerticalScrollBarWidth - 20;
+ tmpPanel.Height = 50;
+ tmpPanel.Location = new Point(5, (i * 55));
+ tmpPanel.BorderStyle = BorderStyle.FixedSingle;
+ tmpPanel.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background-alt"]);
+ tmpPanel.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground-alt"]);
+ tmpPanel.Controls.Add(
+ new Label()
+ {
+ Text = "Date: " + date,
+ Location = new Point(10, 5)
+ }
+ );
+ int confirmations = Convert.ToInt32(tx["confirmations"].ToString());
+ if (mainForm.UserSettings.ContainsKey("confirmations"))
+ {
+ if (confirmations < Convert.ToInt32(mainForm.UserSettings["confirmations"]))
+ {
+ Label txPending = new Label()
+ {
+ Text = "Pending",
+ Location = new Point(100, 5)
+ };
+ tmpPanel.Controls.Add(txPending);
+ txPending.BringToFront();
+ }
+ }
+ Label labelHash = new Label()
+ {
+ Text = "Hash: " + hash.Substring(0, 10) + "..." + hash.Substring(hash.Length - 10),
+ AutoSize = true,
+ Location = new Point(10, 25)
+ };
+
+ tmpPanel.Controls.Add(labelHash);
+
+ JArray inputs = JArray.Parse(tx["inputs"].ToString());
+ JArray outputs = JArray.Parse(tx["outputs"].ToString());
+ int inputCount = inputs.Count;
+ int outputCount = outputs.Count;
+
+ decimal costHNS = decimal.Parse(txs[toGet - i - 1]["amount"].ToString());
+ transaction.Amount = costHNS;
+ string cost = "";
+ if (costHNS < 0)
+ {
+ cost = "Spent: " + (costHNS * -1).ToString() + " HNS";
+ }
+ else if (costHNS > 0)
+ {
+ cost = "Received: " + costHNS.ToString() + " HNS";
+ }
+
+ Label labelInputOutput = new Label()
+ {
+ Text = "Inputs: " + inputCount + " Outputs: " + outputCount + "\n" + cost,
+ AutoSize = true,
+ Location = new Point(300, 5)
+ };
+ tmpPanel.Controls.Add(labelInputOutput);
+
+
+ tmpPanel.Click += (sender, e) =>
+ {
+ TXForm txForm = new TXForm(mainForm, hash);
+ txForm.Show();
+ };
+ foreach (Control c in tmpPanel.Controls)
+ {
+ c.Click += (sender, e) =>
+ {
+ TXForm txForm = new TXForm(mainForm, hash);
+ txForm.Show();
+ };
+ }
+ tmpControls[i] = tmpPanel;
+
+
+ // Outputs
+ foreach (JObject output in outputs)
+ {
+ Output tmpOutput = new Output();
+ tmpOutput.Address = output["address"].ToString();
+ tmpOutput.Amount = decimal.Parse(output["value"].ToString());
+ // Convert amount to HNS
+ tmpOutput.Amount = tmpOutput.Amount / 1000000;
+ JObject covenant = (JObject)output["covenant"];
+
+ if (output["path"].ToString() != "")
+ {
+ tmpOutput.Own = true;
+ }
+ if (covenant.ContainsKey("action"))
+ {
+ tmpOutput.Covenant = covenant["action"].ToString();
+ tmpOutput.Name = "";
+ if (covenant["action"].ToString() != "NONE")
+ {
+
+ JArray items = (JArray)covenant["items"];
+ string namehash = items[0].ToString();
+ string content = "{\"method\": \"getnamebyhash\", \"params\": [\"" + namehash + "\"]}";
+ JObject name = JObject.Parse(await mainForm.APIPost("", false, content));
+ tmpOutput.Name = name["result"].ToString();
+ }
+ }
+ else
+ {
+ tmpOutput.Covenant = "NONE";
+ tmpOutput.Name = "";
+ }
+ transaction.Outputs.Add(tmpOutput);
+ }
+
+ TXs.Add(transaction);
+ }
+ groupBoxTXs.Controls.Clear();
+ Panel txPanel = new Panel();
+ txPanel.Width = groupBoxTXs.Width - SystemInformation.VerticalScrollBarWidth;
+ txPanel.Controls.AddRange(tmpControls);
+ txPanel.AutoScroll = true;
+ txPanel.Dock = DockStyle.Fill;
+ groupBoxTXs.Controls.Add(txPanel);
+ }
+
+ private async void buttonRefresh_Click(object sender, EventArgs e)
+ {
+ this.Enabled = false;
+ await GetTXs();
+ this.Enabled = true;
+ }
+
+ private async void buttonExport_Click(object sender, EventArgs e)
+ {
+ this.Enabled = false;
+ await GetTXs();
+ string filter = comboBoxFilter.Text;
+ if (filter == "ALL")
+ {
+ filter = "";
+ }
+
+ //List filteredTXs = TXs.Where(tx => tx.Filter(filter)).ToList();
+ List filteredTXs = TXs.FindAll(tx => tx.Filter(filter));
+
+ JArray outputJson = new JArray();
+ foreach (Transaction tx in filteredTXs)
+ {
+ //outputJson += tx.ToString(filter) + "\n";
+ outputJson.Add(tx.ToJson(filter));
+ }
+ this.Enabled = true;
+ SaveFileDialog saveFileDialog = new SaveFileDialog();
+ saveFileDialog.Filter = "JSON File|*.json";
+ saveFileDialog.Title = "Save JSON File";
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ try
+ {
+ File.WriteAllText(saveFileDialog.FileName, outputJson.ToString());
+ } catch
+ {
+ NotifyForm notifyForm = new NotifyForm("Error saving JSON file");
+ notifyForm.ShowDialog();
+ notifyForm.Dispose();
+ }
+ }
+
+ }
+ }
+ public class Transaction
+ {
+ public string Hash { get; set; }
+ public DateTime Date { get; set; }
+ public int Confirmations { get; set; }
+ public decimal Amount { get; set; }
+ public List