42 Commits

Author SHA1 Message Date
6218b337fb main: Added Yubikey device check and removed redundant code
- Added a check for the number of connected Yubikeys
- Removed redundant code that prompts user to insert Yubikey before unlocking.
2023-06-15 19:31:24 +10:00
79350570fd main: Added YubiKey
- Added a reference to the Yubico.YubiKey package in FireWallet.csproj

MainForm.cs: Added Yubikey login functionality
- Added code to use a connected Yubikey to encrypt and decrypt account passwords for login.

MainForm.Designer.cs: Added button for Yubikey settings
- Created a button for users to access the settings for using their Yubikey.
2023-06-15 19:08:55 +10:00
88c6b5afe0 README.md: Added instructions for using HIP-02
- Added instructions for using HIP-02 to send HNS to Handshake addresses or domains.
- To use HIP-02, a user needs to have an HSD resolver listening on port 5350.
- A domain must be prefixed with `@` to use HIP-02 (e.g., `@nathan.woodburn`).
2023-06-15 17:38:05 +10:00
f06bc5b711 mainForm.cs: Added domain sorting feature and updated UI
- Added comboBoxDomainSort_DropDownClosed method to update domains
- Added comboBoxDomainSort control to panelDomains
- Added labelDomainSort control to MainForm.Designer.cs
- Updated UpdateDomains method to sort domains based on selected option
2023-06-15 16:47:59 +10:00
42536e47bb README.md: Added a note about BID import syntax
- Added a note about the BID import syntax being BID,LOCKUP where LOCKUP is (BID+BLIND)
2023-06-15 16:43:51 +10:00
404a47ec79 batchForm.cs: Added try-catch block to handle file in use exceptions
- Added try-catch block to handle exceptions when importing batch
- Displayed error message and notification form if an exception occurs
2023-06-15 16:21:13 +10:00
c3abd0b4de README.md: Added ability to send HNS using HIP-02
- Added option to send HNS to Handshake addresses or domains
- Implemented [HIP-02](https://github.com/handshake-org/HIPs/blob/master/HIP-0002.md) for sending HNS
2023-06-15 14:07:26 +10:00
41a38e2af1 package: Increased version 2023-06-15 14:00:48 +10:00
699b1051d4 main: Finished HIP-02 sending 2023-06-15 13:56:24 +10:00
14cb5453dc main: HIP-02 transfers for domains 2023-06-15 13:55:51 +10:00
5323a8ff0d main: Added HIP-02 to sending HNS 2023-06-15 13:46:45 +10:00
2572b17898 main: Don't install HSD if custom path specified 2023-06-15 12:21:15 +10:00
a8f425434e config: Added custom HSD launch command
- Added `HSD` and `HSD-command` keys to node.txt file
- Users can now set a custom HSD launch command by setting the `hsd-command` key in node.txt
- README.md updated with instructions on how to set a custom HSD launch command using `{default-dir}`, `{key}` and `{Bob}`
- Support section added to README.md
2023-06-15 00:00:37 +10:00
07c9618837 tx: Show inputs while outputs are loading 2023-06-14 23:27:50 +10:00
eccc584b2c main: Fixed error check in reveal all 2023-06-14 23:27:28 +10:00
cf2f68f2b3 main: Added support for custom HSD launch command 2023-06-14 23:27:13 +10:00
5eb80bcd06 main: Added help menu 2023-06-14 17:30:50 +10:00
7c38bfc755 main: Move log if it is getting big 2023-06-14 17:19:06 +10:00
d4620af384 batch: Removed old file writing for ledger 2023-06-14 17:08:10 +10:00
15cb4efaf1 package: Increased version 2023-06-14 17:04:14 +10:00
18607358bf TX: Fixed watchonly errors 2023-06-14 17:04:00 +10:00
6db6d02e9e TXs: Fixed decimal errors 2023-06-14 16:57:07 +10:00
3eda3d7419 hsd-ledger added sendraw to usage 2023-06-14 16:30:49 +10:00
3f6c2bdded hsd-ledger: Removed using files to store batch info 2023-06-14 16:30:05 +10:00
2bfca908a9 batch: Changed sendRaw in hsd-ledger 2023-06-14 16:29:22 +10:00
531d41a413 main: Fixed showing TXs for Ledger 2023-06-14 16:29:00 +10:00
960af0b169 main: fixed settings location 2023-06-14 15:49:56 +10:00
14a685690c package: Increased version 2023-06-14 15:29:22 +10:00
816e16a9aa main: On load bring to front 2023-06-14 15:28:59 +10:00
036819169d tx: Get TX on load to lower memory use 2023-06-14 15:20:08 +10:00
1675ac48f3 main: Only get the number of TXs needed
This should speed up the loading on larger wallets
2023-06-14 15:19:16 +10:00
f44aac35f0 domain: Removed OPEN button from reserved domains 2023-06-14 14:09:20 +10:00
bf2e41058d main: Fixed click on text in domains and tx history doesn't open window 2023-06-14 14:07:03 +10:00
2109879f93 Merge remote-tracking branch 'origin/master' 2023-06-13 23:58:32 +10:00
112b719d78 main: Fixed npm installed checks and fixed HSD install 2023-06-13 23:58:24 +10:00
2395c4ca29 main: Fixed npm installed checks 2023-06-13 23:57:10 +10:00
752d20f369 main: Updated version 2023-06-13 23:26:16 +10:00
dc53d7eb0f assets: removed tmp logo 2023-06-13 23:26:06 +10:00
3783cfe759 main: Added error checks in case HSD doesn't start 2023-06-13 23:04:16 +10:00
71395f253b main: Added agent to internal HSD node 2023-06-13 22:51:48 +10:00
b34c6507b8 domains: Fixed opening domain error 2023-06-13 22:51:23 +10:00
b93c981fcd main: Added better errors for git, node or npm not installed 2023-06-13 11:30:54 +10:00
14 changed files with 1142 additions and 254 deletions

View File

@@ -538,14 +538,8 @@ namespace FireWallet
notifyForm.Dispose();
return;
}
StreamWriter sw = new StreamWriter(dir + "hsd-ledger/bin/names.txt");
string domainslist = string.Join(",", batches.Select(batch => batch.domain));
sw.Write(domainslist);
sw.Dispose();
StreamWriter sw2 = new StreamWriter(dir + "hsd-ledger/bin/batch.json");
sw2.Write(response);
sw2.Dispose();
string domainslist = string.Join(",", batches.Select(batch => "\\\"" + batch.domain + "\\\""));
NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false);
notify.Show();
@@ -558,7 +552,9 @@ namespace FireWallet
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "node.exe";
proc.StartInfo.WorkingDirectory = dir + "hsd-ledger/bin/";
proc.StartInfo.Arguments = dir + "hsd-ledger/bin/hsd-ledger sendraw batch.json names.txt --api-key " + mainForm.nodeSettings["Key"] + " -w " + mainForm.account;
string args = "hsd-ledger/bin/hsd-ledger sendraw \"\"" + response.Replace("\"","\\\"") + "\"\" [" + domainslist + "] --api-key " + mainForm.nodeSettings["Key"] + " -w " + mainForm.account;
proc.StartInfo.Arguments = dir + args;
var outputBuilder = new StringBuilder();
// Event handler for capturing output data
@@ -590,6 +586,8 @@ namespace FireWallet
}
else
{
AddLog(args);
AddLog(proc.StandardError.ReadToEnd());
NotifyForm notifyError = new NotifyForm("Error Transaction Failed\nCheck logs for more details");
notifyError.ShowDialog();
notifyError.Dispose();
@@ -640,17 +638,45 @@ namespace FireWallet
openFileDialog.Title = "Open Batch";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
StreamReader sr = new StreamReader(openFileDialog.FileName);
string line;
string[] domains = new string[0];
while ((line = sr.ReadLine()) != null)
try
{
string[] split = line.Split(',');
try
StreamReader sr = new StreamReader(openFileDialog.FileName);
string line;
string[] domains = new string[0];
while ((line = sr.ReadLine()) != null)
{
if (split.Length > 2)
string[] split = line.Split(',');
try
{
if (split[1] == "UPDATE")
if (split.Length > 2)
{
if (split[1] == "UPDATE")
{
// Select operation and import domains
string[] newDomains = new string[domains.Length + 1];
for (int i = 0; i < domains.Length; i++)
{
newDomains[i] = domains[i];
}
newDomains[domains.Length] = split[0];
domains = newDomains;
continue;
}
}
if (split.Length == 2)
{
AddBatch(split[0], split[1]);
}
else if (split.Length == 3)
{
AddBatch(split[0], split[1], split[2]);
}
else if (split.Length == 4)
{
AddBatch(split[0], split[1], Convert.ToDecimal(split[2]), Convert.ToDecimal(split[3]));
}
else
{
// Select operation and import domains
string[] newDomains = new string[domains.Length + 1];
@@ -658,68 +684,49 @@ namespace FireWallet
{
newDomains[i] = domains[i];
}
newDomains[domains.Length] = split[0];
newDomains[domains.Length] = line.Trim();
domains = newDomains;
continue;
}
}
if (split.Length == 2)
catch (Exception ex)
{
AddBatch(split[0], split[1]);
}
else if (split.Length == 3)
{
AddBatch(split[0], split[1], split[2]);
}
else if (split.Length == 4)
{
AddBatch(split[0], split[1], Convert.ToDecimal(split[2]), Convert.ToDecimal(split[3]));
}
else
{
// Select operation and import domains
string[] newDomains = new string[domains.Length + 1];
for (int i = 0; i < domains.Length; i++)
{
newDomains[i] = domains[i];
}
newDomains[domains.Length] = line.Trim();
domains = newDomains;
AddLog("Error importing batch: " + ex.Message);
NotifyForm notifyForm = new NotifyForm("Error importing batch");
notifyForm.ShowDialog();
notifyForm.Dispose();
}
}
catch (Exception ex)
if (domains.Length > 0)
{
AddLog("Error importing batch: " + ex.Message);
NotifyForm notifyForm = new NotifyForm("Error importing batch");
notifyForm.ShowDialog();
notifyForm.Dispose();
BatchImportForm batchImportForm = new BatchImportForm(domains);
batchImportForm.ShowDialog();
if (batchImportForm.batches != null)
{
foreach (Batch b in batchImportForm.batches)
{
if (b.method == "BID")
{
AddBatch(b.domain, b.method, b.bid, b.lockup);
}
else if (b.method == "TRANSFER")
{
AddBatch(b.domain, b.method, b.toAddress);
}
else
{
AddBatch(b.domain, b.method);
}
}
}
}
}
if (domains.Length > 0)
sr.Dispose();
} catch (Exception ex)
{
BatchImportForm batchImportForm = new BatchImportForm(domains);
batchImportForm.ShowDialog();
if (batchImportForm.batches != null)
{
foreach (Batch b in batchImportForm.batches)
{
if (b.method == "BID")
{
AddBatch(b.domain, b.method, b.bid, b.lockup);
}
else if (b.method == "TRANSFER")
{
AddBatch(b.domain, b.method, b.toAddress);
}
else
{
AddBatch(b.domain, b.method);
}
}
}
AddLog("Error importing batch: " + ex.Message);
NotifyForm notifyForm = new NotifyForm("Error importing batch\nMake sure the file is in not in use");
notifyForm.ShowDialog();
notifyForm.Dispose();
}
sr.Dispose();
}
}

View File

@@ -32,36 +32,7 @@ namespace FireWallet
this.explorerTX = explorerTX;
this.explorerName = explorerName;
this.mainForm = mainForm;
}
#region Theming
private void UpdateTheme()
{
// Check if file exists
if (!Directory.Exists(dir))
{
CreateConfig(dir);
}
if (!File.Exists(dir + "theme.txt"))
{
CreateConfig(dir);
}
// Read file
StreamReader sr = new StreamReader(dir + "theme.txt");
theme = new Dictionary<string, string>();
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
string[] split = line.Split(':');
theme.Add(split[0].Trim(), split[1].Trim());
}
sr.Dispose();
if (!theme.ContainsKey("background") || !theme.ContainsKey("background-alt") || !theme.ContainsKey("foreground") || !theme.ContainsKey("foreground-alt"))
{
return;
}
this.theme = mainForm.theme;
// Apply theme
this.BackColor = ColorTranslator.FromHtml(theme["background"]);
@@ -73,35 +44,12 @@ namespace FireWallet
// Need to specify this for each groupbox to override the black text
foreach (Control c in Controls)
{
ThemeControl(c);
mainForm.ThemeControl(c);
}
// Transparancy
applyTransparency(theme);
applyTransparency(mainForm.theme);
}
private void ThemeControl(Control c)
{
if (c.GetType() == typeof(GroupBox) || c.GetType() == typeof(Panel))
{
c.ForeColor = ColorTranslator.FromHtml(theme["foreground"]);
foreach (Control sub in c.Controls)
{
ThemeControl(sub);
}
}
if (c.GetType() == typeof(TextBox) || c.GetType() == typeof(Button)
|| c.GetType() == typeof(ComboBox) || c.GetType() == typeof(StatusStrip))
{
c.ForeColor = ColorTranslator.FromHtml(theme["foreground-alt"]);
c.BackColor = ColorTranslator.FromHtml(theme["background-alt"]);
}
}
#region Theme
private void applyTransparency(Dictionary<string, string> theme)
{
if (theme.ContainsKey("transparent-mode"))
@@ -148,26 +96,6 @@ namespace FireWallet
}
}
}
private void CreateConfig(string dir)
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
StreamWriter sw = new StreamWriter(dir + "theme.txt");
sw.WriteLine("background: #000000");
sw.WriteLine("foreground: #8e05c2");
sw.WriteLine("background-alt: #3e065f");
sw.WriteLine("foreground-alt: #ffffff");
sw.WriteLine("transparent-mode: off");
sw.WriteLine("transparency-key: main");
sw.WriteLine("transparency-percent: 90");
sw.Dispose();
}
// Required for mica effect
internal enum AccentState
{
@@ -209,7 +137,6 @@ namespace FireWallet
private void DomainForm_Load(object sender, EventArgs e)
{
UpdateTheme();
own = false;
StreamReader sr = new StreamReader(dir + "node.txt");
nodeSettings = new Dictionary<string, string>();
@@ -330,6 +257,14 @@ namespace FireWallet
{
labelStatusMain.Text = "Error";
}
if (labelStatusReserved.Text == "True")
{
buttonActionAlt.Hide();
buttonActionMain.Hide();
groupBoxAction.Text = "Reserved";
}
}
catch (Exception ex)
{
@@ -804,9 +739,6 @@ namespace FireWallet
}
else if (state == "AVAILABLE")
{
decimal bid = Convert.ToDecimal(textBoxBid.Text);
decimal blind = Convert.ToDecimal(textBoxBlind.Text);
decimal lockup = bid + blind;
string content = "{\"method\": \"sendopen\", \"params\": [\"" + domain + "\"]}";
string response = await APIPost("", true, content);

View File

@@ -12,7 +12,7 @@
<PackageIcon>HSDBatcher.png</PackageIcon>
<RepositoryUrl>https://github.com/Nathanwoodburn/FireWallet</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>2.4</Version>
<Version>3.0</Version>
</PropertyGroup>
<ItemGroup>
@@ -27,8 +27,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DnsClient" Version="1.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="QRCoder" Version="1.4.3" />
<PackageReference Include="Yubico.YubiKey" Version="1.7.0" />
</ItemGroup>
<ItemGroup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -41,6 +41,10 @@ namespace FireWallet
toolStripStatusLabelaccount = new ToolStripStatusLabel();
toolStripStatusLabelLedger = new ToolStripStatusLabel();
toolStripSplitButtonlogout = new ToolStripSplitButton();
toolStripDropDownButtonHelp = new ToolStripDropDownButton();
githubToolStripMenuItem = new ToolStripMenuItem();
websiteToolStripMenuItem = new ToolStripMenuItem();
supportDiscordServerToolStripMenuItem = new ToolStripMenuItem();
timerNodeStatus = new System.Windows.Forms.Timer(components);
panelaccount = new Panel();
groupBoxaccount = new GroupBox();
@@ -59,7 +63,6 @@ namespace FireWallet
buttonNavSend = new Button();
buttonNavPortfolio = new Button();
panelPortfolio = new Panel();
buttonRenewAll = new Button();
buttonRevealAll = new Button();
groupBoxTransactions = new GroupBox();
groupBoxinfo = new GroupBox();
@@ -70,7 +73,9 @@ namespace FireWallet
labelBalanceTotal = new Label();
labelLocked = new Label();
labelBalance = new Label();
buttonRenewAll = new Button();
panelSend = new Panel();
labelSendingHIPAddress = new Label();
checkBoxSendSubFee = new CheckBox();
buttonSendMax = new Button();
buttonSendHNS = new Button();
@@ -82,6 +87,7 @@ namespace FireWallet
labelSendingAmount = new Label();
labelSendingTo = new Label();
labelSendPrompt = new Label();
labelHIPArrow = new Label();
panelRecieve = new Panel();
buttonAddressVerify = new Button();
pictureBoxReceiveQR = new PictureBox();
@@ -89,6 +95,8 @@ namespace FireWallet
textBoxReceiveAddress = new TextBox();
labelReceive1 = new Label();
panelDomains = new Panel();
labelDomainSort = new Label();
comboBoxDomainSort = new ComboBox();
buttonExportDomains = new Button();
groupBoxDomains = new GroupBox();
panelDomainList = new Panel();
@@ -96,6 +104,7 @@ namespace FireWallet
textBoxDomainSearch = new TextBox();
panelSettings = new Panel();
groupBoxSettingsWallet = new GroupBox();
buttonSettingsYubikey = new Button();
buttonSettingsRescan = new Button();
buttonSeed = new Button();
groupBoxSettingsMisc = new GroupBox();
@@ -139,7 +148,7 @@ namespace FireWallet
// statusStripmain
//
statusStripmain.Dock = DockStyle.Top;
statusStripmain.Items.AddRange(new ToolStripItem[] { toolStripStatusLabelNetwork, toolStripStatusLabelstatus, toolStripStatusLabelaccount, toolStripStatusLabelLedger, toolStripSplitButtonlogout });
statusStripmain.Items.AddRange(new ToolStripItem[] { toolStripStatusLabelNetwork, toolStripStatusLabelstatus, toolStripStatusLabelaccount, toolStripStatusLabelLedger, toolStripSplitButtonlogout, toolStripDropDownButtonHelp });
statusStripmain.Location = new Point(0, 0);
statusStripmain.Name = "statusStripmain";
statusStripmain.Size = new Size(1152, 22);
@@ -190,6 +199,39 @@ namespace FireWallet
toolStripSplitButtonlogout.Visible = false;
toolStripSplitButtonlogout.ButtonClick += Logout;
//
// toolStripDropDownButtonHelp
//
toolStripDropDownButtonHelp.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripDropDownButtonHelp.DropDownItems.AddRange(new ToolStripItem[] { githubToolStripMenuItem, websiteToolStripMenuItem, supportDiscordServerToolStripMenuItem });
toolStripDropDownButtonHelp.Image = (Image)resources.GetObject("toolStripDropDownButtonHelp.Image");
toolStripDropDownButtonHelp.ImageTransparentColor = Color.Magenta;
toolStripDropDownButtonHelp.Margin = new Padding(20, 2, 0, 0);
toolStripDropDownButtonHelp.Name = "toolStripDropDownButtonHelp";
toolStripDropDownButtonHelp.Size = new Size(45, 20);
toolStripDropDownButtonHelp.Text = "Help";
toolStripDropDownButtonHelp.ToolTipText = "Help";
//
// githubToolStripMenuItem
//
githubToolStripMenuItem.Name = "githubToolStripMenuItem";
githubToolStripMenuItem.Size = new Size(194, 22);
githubToolStripMenuItem.Text = "Github";
githubToolStripMenuItem.Click += githubToolStripMenuItem_Click;
//
// websiteToolStripMenuItem
//
websiteToolStripMenuItem.Name = "websiteToolStripMenuItem";
websiteToolStripMenuItem.Size = new Size(194, 22);
websiteToolStripMenuItem.Text = "Website";
websiteToolStripMenuItem.Click += websiteToolStripMenuItem_Click;
//
// supportDiscordServerToolStripMenuItem
//
supportDiscordServerToolStripMenuItem.Name = "supportDiscordServerToolStripMenuItem";
supportDiscordServerToolStripMenuItem.Size = new Size(194, 22);
supportDiscordServerToolStripMenuItem.Text = "Support Discord Server";
supportDiscordServerToolStripMenuItem.Click += supportDiscordServerToolStripMenuItem_Click;
//
// timerNodeStatus
//
timerNodeStatus.Enabled = true;
@@ -200,7 +242,7 @@ namespace FireWallet
//
panelaccount.BackColor = Color.Transparent;
panelaccount.Controls.Add(groupBoxaccount);
panelaccount.Location = new Point(1082, 211);
panelaccount.Location = new Point(132, 30);
panelaccount.Name = "panelaccount";
panelaccount.Size = new Size(1074, 642);
panelaccount.TabIndex = 1;
@@ -400,18 +442,6 @@ namespace FireWallet
panelPortfolio.TabIndex = 7;
panelPortfolio.Visible = false;
//
// buttonRenewAll
//
buttonRenewAll.FlatStyle = FlatStyle.Flat;
buttonRenewAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonRenewAll.Location = new Point(813, 9);
buttonRenewAll.Name = "buttonRenewAll";
buttonRenewAll.Size = new Size(89, 32);
buttonRenewAll.TabIndex = 10;
buttonRenewAll.Text = "Renew All";
buttonRenewAll.UseVisualStyleBackColor = true;
buttonRenewAll.Click += buttonRenewAll_Click;
//
// buttonRevealAll
//
buttonRevealAll.FlatStyle = FlatStyle.Flat;
@@ -518,8 +548,21 @@ namespace FireWallet
labelBalance.TabIndex = 0;
labelBalance.Text = "labelBalance";
//
// buttonRenewAll
//
buttonRenewAll.FlatStyle = FlatStyle.Flat;
buttonRenewAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonRenewAll.Location = new Point(813, 9);
buttonRenewAll.Name = "buttonRenewAll";
buttonRenewAll.Size = new Size(89, 32);
buttonRenewAll.TabIndex = 10;
buttonRenewAll.Text = "Renew All";
buttonRenewAll.UseVisualStyleBackColor = true;
buttonRenewAll.Click += buttonRenewAll_Click;
//
// panelSend
//
panelSend.Controls.Add(labelSendingHIPAddress);
panelSend.Controls.Add(checkBoxSendSubFee);
panelSend.Controls.Add(buttonSendMax);
panelSend.Controls.Add(buttonSendHNS);
@@ -531,12 +574,23 @@ namespace FireWallet
panelSend.Controls.Add(labelSendingAmount);
panelSend.Controls.Add(labelSendingTo);
panelSend.Controls.Add(labelSendPrompt);
panelSend.Location = new Point(1113, 42);
panelSend.Controls.Add(labelHIPArrow);
panelSend.Location = new Point(880, 441);
panelSend.Name = "panelSend";
panelSend.Size = new Size(974, 521);
panelSend.TabIndex = 2;
panelSend.Visible = false;
//
// labelSendingHIPAddress
//
labelSendingHIPAddress.AutoSize = true;
labelSendingHIPAddress.Location = new Point(375, 130);
labelSendingHIPAddress.Name = "labelSendingHIPAddress";
labelSendingHIPAddress.Size = new Size(64, 15);
labelSendingHIPAddress.TabIndex = 17;
labelSendingHIPAddress.Text = "To Address";
labelSendingHIPAddress.Visible = false;
//
// checkBoxSendSubFee
//
checkBoxSendSubFee.AutoSize = true;
@@ -579,11 +633,11 @@ namespace FireWallet
//
labelSendingError.AutoSize = true;
labelSendingError.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
labelSendingError.Location = new Point(615, 131);
labelSendingError.Location = new Point(679, 130);
labelSendingError.Name = "labelSendingError";
labelSendingError.Size = new Size(52, 21);
labelSendingError.Size = new Size(78, 21);
labelSendingError.TabIndex = 13;
labelSendingError.Text = "label1";
labelSendingError.Text = "labelError";
labelSendingError.Visible = false;
//
// labelSendingFee
@@ -654,6 +708,17 @@ namespace FireWallet
labelSendPrompt.TabIndex = 0;
labelSendPrompt.Text = "Send HNS";
//
// labelHIPArrow
//
labelHIPArrow.AutoSize = true;
labelHIPArrow.Font = new Font("Segoe UI", 18F, FontStyle.Bold, GraphicsUnit.Point);
labelHIPArrow.Location = new Point(346, 119);
labelHIPArrow.Name = "labelHIPArrow";
labelHIPArrow.Size = new Size(32, 32);
labelHIPArrow.TabIndex = 18;
labelHIPArrow.Text = "⮡ ";
labelHIPArrow.Visible = false;
//
// panelRecieve
//
panelRecieve.Controls.Add(buttonAddressVerify);
@@ -721,17 +786,42 @@ namespace FireWallet
//
// panelDomains
//
panelDomains.Controls.Add(labelDomainSort);
panelDomains.Controls.Add(comboBoxDomainSort);
panelDomains.Controls.Add(buttonRenewAll);
panelDomains.Controls.Add(buttonExportDomains);
panelDomains.Controls.Add(groupBoxDomains);
panelDomains.Controls.Add(labelDomainSearch);
panelDomains.Controls.Add(textBoxDomainSearch);
panelDomains.Location = new Point(120, 48);
panelDomains.Location = new Point(861, 364);
panelDomains.Name = "panelDomains";
panelDomains.Size = new Size(920, 536);
panelDomains.TabIndex = 18;
panelDomains.Visible = false;
//
// labelDomainSort
//
labelDomainSort.AutoSize = true;
labelDomainSort.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
labelDomainSort.Location = new Point(638, 15);
labelDomainSort.Name = "labelDomainSort";
labelDomainSort.Size = new Size(42, 21);
labelDomainSort.TabIndex = 12;
labelDomainSort.Text = "Sort:";
//
// comboBoxDomainSort
//
comboBoxDomainSort.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxDomainSort.FlatStyle = FlatStyle.Flat;
comboBoxDomainSort.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
comboBoxDomainSort.FormattingEnabled = true;
comboBoxDomainSort.Items.AddRange(new object[] { "Default", "Alphabetical", "Expiring", "Value" });
comboBoxDomainSort.Location = new Point(686, 12);
comboBoxDomainSort.Name = "comboBoxDomainSort";
comboBoxDomainSort.Size = new Size(121, 29);
comboBoxDomainSort.TabIndex = 11;
comboBoxDomainSort.DropDownClosed += comboBoxDomainSort_DropDownClosed;
//
// buttonExportDomains
//
buttonExportDomains.FlatStyle = FlatStyle.Flat;
@@ -792,7 +882,7 @@ namespace FireWallet
panelSettings.Controls.Add(buttonSettingsSave);
panelSettings.Controls.Add(groupBoxSettingsExplorer);
panelSettings.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
panelSettings.Location = new Point(1065, 211);
panelSettings.Location = new Point(848, 306);
panelSettings.Name = "panelSettings";
panelSettings.Size = new Size(930, 550);
panelSettings.TabIndex = 19;
@@ -800,6 +890,7 @@ namespace FireWallet
//
// groupBoxSettingsWallet
//
groupBoxSettingsWallet.Controls.Add(buttonSettingsYubikey);
groupBoxSettingsWallet.Controls.Add(buttonSettingsRescan);
groupBoxSettingsWallet.Controls.Add(buttonSeed);
groupBoxSettingsWallet.Location = new Point(507, 16);
@@ -809,6 +900,17 @@ namespace FireWallet
groupBoxSettingsWallet.TabStop = false;
groupBoxSettingsWallet.Text = "Wallet Controls";
//
// buttonSettingsYubikey
//
buttonSettingsYubikey.FlatStyle = FlatStyle.Flat;
buttonSettingsYubikey.Location = new Point(6, 133);
buttonSettingsYubikey.Name = "buttonSettingsYubikey";
buttonSettingsYubikey.Size = new Size(98, 50);
buttonSettingsYubikey.TabIndex = 9;
buttonSettingsYubikey.Text = "YubiKey";
buttonSettingsYubikey.UseVisualStyleBackColor = true;
buttonSettingsYubikey.Click += buttonSettingsYubikey_Click;
//
// buttonSettingsRescan
//
buttonSettingsRescan.FlatStyle = FlatStyle.Flat;
@@ -1008,13 +1110,13 @@ namespace FireWallet
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1152, 575);
Controls.Add(panelaccount);
Controls.Add(panelPortfolio);
Controls.Add(panelRecieve);
Controls.Add(panelSettings);
Controls.Add(panelDomains);
Controls.Add(panelSend);
Controls.Add(panelPortfolio);
Controls.Add(panelRecieve);
Controls.Add(panelNav);
Controls.Add(statusStripmain);
Controls.Add(panelSettings);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "MainForm";
Opacity = 0D;
@@ -1137,5 +1239,14 @@ namespace FireWallet
private Button buttonRevealAll;
private Button buttonExportDomains;
private Button buttonRenewAll;
private ToolStripDropDownButton toolStripDropDownButtonHelp;
private ToolStripMenuItem githubToolStripMenuItem;
private ToolStripMenuItem websiteToolStripMenuItem;
private ToolStripMenuItem supportDiscordServerToolStripMenuItem;
private Label labelHIPArrow;
private Label labelSendingHIPAddress;
private ComboBox comboBoxDomainSort;
private Label labelDomainSort;
private Button buttonSettingsYubikey;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -120,10 +120,19 @@
<metadata name="statusStripmain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>133, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="toolStripDropDownButtonHelp.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb
J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj
CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN
AAAAAElFTkSuQmCC
</value>
</data>
<metadata name="timerNodeStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>269, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAAAAAAAEAIAB2pAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAOEAAADAAgGAAAAfG+p9QAAIABJ

View File

@@ -17,7 +17,8 @@ namespace FireWallet
{
MainForm mainForm;
JObject tx;
public TXForm(MainForm mainForm, JObject tx)
string txid;
public TXForm(MainForm mainForm, string txid)
{
InitializeComponent();
// Theme
@@ -29,16 +30,20 @@ namespace FireWallet
}
this.mainForm = mainForm;
this.tx = tx;
this.Text = "TX: " + tx["hash"].ToString();
this.txid = txid;
}
private async void TXForm_Load(object sender, EventArgs e)
{
tx = JObject.Parse(await mainForm.APIGet("wallet/"+mainForm.account+"/tx/" + txid,true));
this.Text = "TX: " + tx["hash"].ToString();
labelHash.Text = "Hash: " + tx["hash"].ToString();
mainForm.AddLog("Viewing TX: " + tx["hash"].ToString());
// Disable scrolling on the panels until they are populated
panelInputs.Visible = false;
panelOutputs.Visible = false;
// For each input
JArray inputs = (JArray)tx["inputs"];
@@ -74,7 +79,7 @@ namespace FireWallet
panelInputs.Controls.Add(PanelInput);
}
panelInputs.Visible = true;
// For each output
JArray outputs = (JArray)tx["outputs"];
foreach (JObject output in outputs)
@@ -131,6 +136,7 @@ namespace FireWallet
panelOutputs.Controls.Add(PanelOutput);
}
panelOutputs.Visible = true;
}
private void Explorer_Click(object sender, EventArgs e)

View File

@@ -36,6 +36,8 @@
label2 = new Label();
textBoxAddress = new TextBox();
labelError = new Label();
labelSendingHIPAddress = new Label();
labelHIPArrow = new Label();
SuspendLayout();
//
// buttonTransfer
@@ -105,18 +107,41 @@
// labelError
//
labelError.AutoSize = true;
labelError.Location = new Point(46, 139);
labelError.Location = new Point(492, 139);
labelError.Name = "labelError";
labelError.Size = new Size(98, 15);
labelError.TabIndex = 6;
labelError.Text = "Address not valid";
labelError.Visible = false;
//
// labelSendingHIPAddress
//
labelSendingHIPAddress.AutoSize = true;
labelSendingHIPAddress.Location = new Point(75, 150);
labelSendingHIPAddress.Name = "labelSendingHIPAddress";
labelSendingHIPAddress.Size = new Size(64, 15);
labelSendingHIPAddress.TabIndex = 19;
labelSendingHIPAddress.Text = "To Address";
labelSendingHIPAddress.Visible = false;
//
// labelHIPArrow
//
labelHIPArrow.AutoSize = true;
labelHIPArrow.Font = new Font("Segoe UI", 18F, FontStyle.Bold, GraphicsUnit.Point);
labelHIPArrow.Location = new Point(46, 139);
labelHIPArrow.Name = "labelHIPArrow";
labelHIPArrow.Size = new Size(32, 32);
labelHIPArrow.TabIndex = 20;
labelHIPArrow.Text = "⮡ ";
labelHIPArrow.Visible = false;
//
// TransferForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(602, 340);
Controls.Add(labelSendingHIPAddress);
Controls.Add(labelHIPArrow);
Controls.Add(labelError);
Controls.Add(textBoxAddress);
Controls.Add(label2);
@@ -143,5 +168,7 @@
private Label label2;
private TextBox textBoxAddress;
private Label labelError;
private Label labelSendingHIPAddress;
private Label labelHIPArrow;
}
}

View File

@@ -8,6 +8,8 @@ using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DnsClient.Protocol;
using DnsClient;
using Newtonsoft.Json.Linq;
namespace FireWallet
@@ -46,16 +48,19 @@ namespace FireWallet
this.Close();
}
string address = "";
private async void buttonTransfer_Click(object sender, EventArgs e)
{
if (!await MainForm.ValidAddress(textBoxAddress.Text))
updateAddress();
if (!await MainForm.ValidAddress(address))
{
labelError.Show();
return;
}
string content = "{\"method\": \"sendtransfer\",\"params\": [ \"" + Domain + "\", \"" +
textBoxAddress.Text + "\"]}";
address + "\"]}";
string output = await MainForm.APIPost("", true, content);
JObject APIresp = JObject.Parse(output);
if (APIresp["error"].ToString() != "")
@@ -78,14 +83,113 @@ namespace FireWallet
private async void buttonBatch_Click(object sender, EventArgs e)
{
if (!await MainForm.ValidAddress(textBoxAddress.Text))
updateAddress();
if (!await MainForm.ValidAddress(address))
{
labelError.Show();
return;
}
MainForm.AddBatch(Domain, "TRANSFER", textBoxAddress.Text);
MainForm.AddBatch(Domain, "TRANSFER", address);
this.Close();
}
private void updateAddress()
{
labelError.Hide();
if (textBoxAddress.Text.Length < 1)
{
address = "";
return;
}
if (textBoxAddress.Text.Substring(0, 1) == "@")
{
string domain = textBoxAddress.Text.Substring(1);
try
{
IPAddress iPAddress = null;
// Create an instance of LookupClient using the custom options
NameServer nameServer = new NameServer(IPAddress.Parse("127.0.0.1"), 5350);
var options = new LookupClientOptions(nameServer);
options.EnableAuditTrail = true;
options.UseTcpOnly = true;
options.Recursion = true;
options.UseCache = false;
options.RequestDnsSecRecords = true;
options.Timeout = TimeSpan.FromSeconds(5);
var client = new LookupClient(options);
// Perform the DNS lookup for the specified domain using DNSSec
var result = client.Query(domain, QueryType.A);
// Display the DNS lookup results
foreach (var record in result.Answers.OfType<ARecord>())
{
iPAddress = record.Address;
}
if (iPAddress == null)
{
labelError.Show();
labelError.Text = "HIP-02 lookup failed";
return;
}
// Get TLSA record
var resultTLSA = client.Query("_443._tcp." + domain, QueryType.TLSA);
foreach (var record in resultTLSA.Answers.OfType<TlsaRecord>())
{
MainForm.TLSA = record.CertificateAssociationDataAsString;
}
string url = "https://" + iPAddress.ToString() + "/.well-known/wallets/HNS";
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = MainForm.ValidateServerCertificate;
// Create an instance of HttpClient with the custom handler
using (var httpclient = new HttpClient(handler))
{
httpclient.DefaultRequestHeaders.Add("Host", domain);
// Send a GET request to the specified URL
HttpResponseMessage response = httpclient.GetAsync(url).Result;
// Response
string address = response.Content.ReadAsStringAsync().Result;
labelSendingHIPAddress.Text = address;
this.address = address;
labelSendingHIPAddress.Show();
labelHIPArrow.Show();
}
}
catch (Exception ex)
{
MainForm.AddLog(ex.Message);
labelError.Show();
labelError.Text = "HIP-02 lookup failed";
}
} else
{
address = textBoxAddress.Text;
}
}
}
}

View File

@@ -224,15 +224,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:FireWallet"
"ProductCode" = "8:{24264791-86B1-49B5-88C9-5042C3FA1BF2}"
"PackageCode" = "8:{8CC25786-EE60-4F7F-970E-D122B84DF8B5}"
"ProductCode" = "8:{007B0A5E-57B9-4DB7-AABE-5A3631A89BEB}"
"PackageCode" = "8:{546D4209-3E58-4144-A9DC-E659A2482DD4}"
"UpgradeCode" = "8:{0C86F725-6B01-4173-AA05-3F0EDF481362}"
"AspNetVersion" = "8:"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:2.4"
"ProductVersion" = "8:3.0"
"Manufacturer" = "8:Nathan.Woodburn/"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:https://l.woodburn.au/discord"

View File

@@ -60,6 +60,9 @@ You can change the number of transactions shown in the `portfolio-tx:` settings.
<br><br>
## Sending HNS
![Send](assets/send_hns.png)
This page lets you send HNS to Handshake addresses or domains using [HIP-02](https://github.com/handshake-org/HIPs/blob/master/HIP-0002.md).
To use HIP-02 you need to have HSD resolver (or any HNS compatible DNS resolver) listening on port 5350 (default HSD port).
To enter a domain to use HIP-02 you need to prefix the domain with `@` (eg. `@nathan.woodburn`).
## Receiving HNS or Domains
The receive page shows your current HNS address.
@@ -104,6 +107,8 @@ The "CANCEL" transaction type is used to cancel an transfer.
At the momemt "UPDATE" or coin only transactions are not supported.
Please not that the import syntax for BIDs is BID,LOCKUP where LOCKUP is (BID+BLIND)
![Batch Import](assets/batch_import.png)
## Exporting
@@ -134,6 +139,15 @@ This file stores the node (HSD/Bob connection) settings.
The Network is the network you want to connect to (default is `0` for Mainnet).
If you delete this file, FireWallet will show the node setup screen on next startup.
You can set a custom HSD launch command by setting the `hsd-command` key.
The default launch is the same as this
```yaml
HSD-command: {default-dir} --agent=FireWallet --index-tx --index-address --api-key {key} --prefix {Bob}
```
The `{default-dir}` will be replaced with the HSD directory `%appdata%\FireWallet\hsd\`.
The `{key}` will be replaced with the API key from the node.txt file.
The `{Bob}` will be replaced with the Bob wallet HSD data directory `%appdata%\Bob\hsd_data\` this is used to sync FireWallet with Bob's accounts and also stops you needing to sync the chain twice.
## theme.txt
This file stores the theme settings.
The theme is the color scheme of the application.
@@ -142,4 +156,10 @@ There are 4 modes: `off` is disabled, `mica` is windows app style, `key` is to m
## log.txt
This file stores the logs for the application.
You should check this file if you have any issues with the application.
You should check this file if you have any issues with the application.
# Support
If you have any issues with the application you can open an issue on GitHub or contact me on Discord (NathanWoodburn on most Handshake servers).
If you would like to support this project you can find out how at https://nathan.woodburn.au/#donate or you can help by contributing to the project on GitHub.

View File

@@ -1,3 +1,5 @@
IP: 127.0.0.1
Network: 0
Key: my-super-secret-api-key
HSD: False
HSD-command: {default-dir} --agent=FireWallet --index-tx --index-address --api-key {key} --prefix {Bob}

View File

@@ -136,20 +136,14 @@ async function sendRaw(wclient, nclient, config, ledger, args) { // Create a fun
const network = Network.get(config.str('network')); // Get the network
const id = config.str('wallet-id'); // Get the wallet id
const acct = config.str('account-name'); // Get the account name
const batch = args[0]; // Get the batch file location
const nameslocation = args[1]; // Get the names file location
// Log the arguments to the console (for debugging)
const batch = JSON.parse(args[0]); // Get the batch
const names = JSON.parse(args[1]); // Get the names
await wclient.execute('selectwallet', [id]); // Select the wallet
const fs = require('fs'); // Import fs (used to read files)
try {
const data = fs.readFileSync(batch, 'utf8'); // Read the batch file
const json = JSON.parse(data); // Parse the batch file as JSON
const mtx = MTX.fromJSON(json.result); // Create a new MTX from the JSON
const namefile = fs.readFileSync(nameslocation, 'utf8'); // Read the names file
const names = namefile.split(','); // Split the names file into an array
const mtx = MTX.fromJSON(batch.result); // Create a new MTX from the JSON
const hashes = {}; // Create an empty object to store the hashes
for (const name of names) { // Loop through the names
const hash = hashName(name); // Hash the name
@@ -428,6 +422,7 @@ function usage(err) {
console.log(' $ hsd-ledger createaccount <account-name> <account-index>');
console.log(' $ hsd-ledger createaddress');
console.log(' $ hsd-ledger sendtoaddress <address> <amount>');
console.log(' $ hsd-ledger sendraw <batch> <names>');
console.log(' $ hsd-ledger getwallets');
console.log(' $ hsd-ledger getaccounts');
console.log(' $ hsd-ledger getaccount <account-name>');