11 Commits
v2.7 ... v3.0

Author SHA1 Message Date
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
10 changed files with 516 additions and 54 deletions

View File

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

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();
@@ -71,6 +75,7 @@ namespace FireWallet
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();
@@ -139,7 +145,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 +196,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;
@@ -520,6 +559,7 @@ namespace FireWallet
//
// panelSend
//
panelSend.Controls.Add(labelSendingHIPAddress);
panelSend.Controls.Add(checkBoxSendSubFee);
panelSend.Controls.Add(buttonSendMax);
panelSend.Controls.Add(buttonSendHNS);
@@ -531,12 +571,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(138, 33);
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 +630,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 +705,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);
@@ -1007,12 +1069,12 @@ namespace FireWallet
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1152, 575);
Controls.Add(panelSend);
Controls.Add(panelSettings);
Controls.Add(panelaccount);
Controls.Add(panelPortfolio);
Controls.Add(panelRecieve);
Controls.Add(panelDomains);
Controls.Add(panelSend);
Controls.Add(panelNav);
Controls.Add(statusStripmain);
Icon = (Icon)resources.GetObject("$this.Icon");
@@ -1137,5 +1199,11 @@ 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;
}
}

View File

@@ -10,6 +10,10 @@ using System.Text;
using System.Security.Policy;
using System.Windows.Forms;
using System.Net;
using DnsClient;
using DnsClient.Protocol;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace FireWallet
{
@@ -48,6 +52,14 @@ namespace FireWallet
timerNodeStatus.Stop();
LoadSettings();
UpdateTheme();
// Theme drop down
foreach (ToolStripMenuItem c in toolStripDropDownButtonHelp.DropDownItems)
{
c.ForeColor = ColorTranslator.FromHtml(theme["foreground"]);
c.BackColor = ColorTranslator.FromHtml(theme["background"]);
}
toolStripDropDownButtonHelp.DropDown.BackColor = ColorTranslator.FromHtml(theme["background"]);
if (await LoadNode() != true) this.Close();
@@ -183,27 +195,36 @@ namespace FireWallet
AddLog("Starting HSD");
toolStripStatusLabelstatus.Text = "Status: HSD Starting";
if (!Directory.Exists(dir + "hsd"))
string hsdPath = dir + "hsd\\bin\\hsd.exe";
if (nodeSettings.ContainsKey("HSD-command"))
{
NotifyForm Notifyinstall = new NotifyForm("Installing hsd\nThis may take a few minutes\nDo not close FireWallet", false);
Notifyinstall.Show();
// Wait for the notification to show
await Task.Delay(1000);
if (nodeSettings["HSD-command"].Contains("{default-dir}"))
{
if (!Directory.Exists(dir + "hsd"))
{
NotifyForm Notifyinstall = new NotifyForm("Installing hsd\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.git";
string destinationPath = dir + "hsd";
CloneRepository(repositoryUrl, destinationPath);
string repositoryUrl = "https://github.com/handshake-org/hsd.git";
string destinationPath = dir + "hsd";
CloneRepository(repositoryUrl, destinationPath);
Notifyinstall.CloseNotification();
Notifyinstall.Dispose();
}
if (!Directory.Exists(dir + "hsd\\node_modules"))
{
AddLog("HSD install failed");
this.Close();
return false;
Notifyinstall.CloseNotification();
Notifyinstall.Dispose();
}
if (!Directory.Exists(dir + "hsd\\node_modules"))
{
AddLog("HSD install failed");
this.Close();
return false;
}
}
}
hsdProcess = new Process();
bool hideScreen = true;
@@ -231,13 +252,41 @@ namespace FireWallet
hsdProcess.StartInfo.RedirectStandardOutput = false;
hsdProcess.StartInfo.UseShellExecute = false;
hsdProcess.StartInfo.FileName = "node.exe";
hsdProcess.StartInfo.Arguments = dir + "hsd/bin/hsd --agent=FireWallet --index-tx --index-address --api-key " + nodeSettings["Key"];
string bobPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Bob\\hsd_data";
if (Directory.Exists(bobPath))
if (nodeSettings.ContainsKey("HSD-command"))
{
hsdProcess.StartInfo.Arguments = hsdProcess.StartInfo.Arguments + " --prefix " + bobPath;
AddLog("Using custom HSD command");
string command = nodeSettings["HSD-command"];
command = command.Replace("{default-dir}", dir + "hsd\\bin\\hsd");
string bobPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Bob\\hsd_data";
if (Directory.Exists(bobPath))
{
command = command.Replace("{Bob}", bobPath);
}
else if (command.Contains("{Bob}"))
{
AddLog("Bob not found, using default HSD command");
command = dir + "hsd\\bin\\hsd --agent=FireWallet --index-tx --index-address --api-key " + nodeSettings["Key"];
}
command = command.Replace("{key}", nodeSettings["Key"]);
hsdProcess.StartInfo.Arguments = command;
}
else
{
AddLog("Using default HSD command");
hsdProcess.StartInfo.Arguments = dir + "hsd\\bin\\hsd --agent=FireWallet --index-tx --index-address --api-key " + nodeSettings["Key"];
string bobPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Bob\\hsd_data";
if (Directory.Exists(bobPath))
{
hsdProcess.StartInfo.Arguments = hsdProcess.StartInfo.Arguments + " --prefix " + bobPath;
}
}
hsdProcess.Start();
// Wait for HSD to start
await Task.Delay(2000);
@@ -308,6 +357,18 @@ namespace FireWallet
public void AddLog(string message)
{
if (message.Contains("Get Error: No connection could be made because the target machine actively refused it")) return;
// If file size is over 1MB, rename it to old.log.txt
if (File.Exists(dir + "log.txt"))
{
FileInfo fi = new FileInfo(dir + "log.txt");
if (fi.Length > 1000000)
{
if (File.Exists(dir + "old.log.txt")) File.Delete(dir + "old.log.txt"); // Delete old log file as it is super old
File.Move(dir + "log.txt", dir + "old.log.txt");
}
}
StreamWriter sw = new StreamWriter(dir + "log.txt", true);
sw.WriteLine(DateTime.Now.ToString() + ": " + message);
sw.Dispose();
@@ -891,7 +952,8 @@ namespace FireWallet
if (watchOnly)
{
APIresponse = await APIPost("", true, "{\"method\": \"listtransactions\",\"params\": [\"default\"," + toGet + "," + toSkip + ", true]}");
} else
}
else
{
APIresponse = await APIPost("", true, "{\"method\": \"listtransactions\",\"params\": [\"default\"," + toGet + "," + toSkip + "]}");
}
@@ -912,10 +974,7 @@ namespace FireWallet
}
JArray txs = JArray.Parse(TXGET["result"].ToString());
if (toGet > txs.Count)
{
toGet = txs.Count;
}
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++)
{
@@ -1029,17 +1088,17 @@ namespace FireWallet
{
try
{
string response = await APIGet("fee", false);
string response = await APIPost("", false, "{\"method\": \"estimatefee\",\"params\": [ 3 ]}");
JObject resp = JObject.Parse(response);
decimal fee = Convert.ToDecimal(resp["rate"].ToString());
fee = fee / 1000000;
if (fee < 0.0001m) fee = 1;
string result = resp["result"].ToString();
decimal fee = decimal.Parse(result);
if (fee < 0.001m) fee = 1;
return fee.ToString();
//return resp["rate"].ToString();
}
catch
{
AddLog("GetFee Error");
return "1";
}
}
@@ -1105,6 +1164,7 @@ namespace FireWallet
labelSendingMax.Text = "Max: " + balance.ToString() + " HNS";
textBoxSendingTo.Focus();
string fee = await GetFee();
labelSendingFee.Text = "Est. Fee: " + fee + " HNS";
labelSendingError.Hide();
@@ -1200,14 +1260,96 @@ namespace FireWallet
}
#endregion
#region Send
// Store TLSA hash
public string TLSA { get; set; }
private async void textBoxSendingTo_Leave(object sender, EventArgs e)
{
labelSendingError.Hide();
labelHIPArrow.Hide();
labelSendingHIPAddress.Hide();
if (textBoxSendingTo.Text == "") return;
if (textBoxSendingTo.Text.Substring(0, 1) == "@")
{
labelSendingError.Show();
labelSendingError.Text = "HIP-02 Not supported yet";
return;
string domain = textBoxSendingTo.Text.Substring(1);
try
{
IPAddress iPAddress = null;
TLSA = "";
// 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)
{
labelSendingError.Show();
labelSendingError.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>())
{
TLSA = record.CertificateAssociationDataAsString;
}
string url = "https://" + iPAddress.ToString() + "/.well-known/wallets/HNS";
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = 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;
labelSendingHIPAddress.Show();
labelHIPArrow.Show();
}
}
catch (Exception ex)
{
AddLog(ex.Message);
labelSendingError.Show();
labelSendingError.Text = "HIP-02 lookup failed";
}
}
else
{
@@ -1232,6 +1374,67 @@ namespace FireWallet
}
}
}
public bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// Customize the certificate validation logic here if needed
// Return true to accept the certificate or false to reject it
X509Certificate2 cert2 = new X509Certificate2(certificate);
var rsaPublicKey = (RSA)cert2.PublicKey.Key;
// Calculate the SHA-256 hash of the public key
using (var sha256 = SHA256.Create())
{
byte[] publicKeyBytes = rsaPublicKey.ExportSubjectPublicKeyInfo();
byte[] publicKeyHash = sha256.ComputeHash(publicKeyBytes);
// Convert the hash value to hexadecimal format
string hexFingerprint = ByteArrayToHexString(publicKeyHash);
if (hexFingerprint == TLSA)
{
return true;
}
else
{
AddLog("TLSA mismatch");
return false;
}
}
}
static string ByteArrayToHexString(byte[] bytes)
{
StringBuilder hex = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
{
hex.AppendFormat("{0:X2}", b);
}
return hex.ToString();
}
private static string GetHash(HashAlgorithm hashAlgorithm, byte[] input)
{
// Convert the input string to a byte array and compute the hash.
byte[] data = hashAlgorithm.ComputeHash(input);
// Create a new Stringbuilder to collect the bytes
// and create a string.
var sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
private void textBoxSendingAmount_Leave(object sender, EventArgs e)
{
decimal amount = 0;
@@ -1259,6 +1462,10 @@ namespace FireWallet
try
{
string address = textBoxSendingTo.Text;
if (labelHIPArrow.Visible)
{
address = labelSendingHIPAddress.Text;
}
bool valid = await ValidAddress(address);
if (!valid)
{
@@ -1758,7 +1965,7 @@ namespace FireWallet
return;
}
JObject resp = JObject.Parse(response);
if (resp["error"] != null)
if (resp["error"].ToString() != "")
{
AddLog("Error sending reveal");
AddLog(resp["error"].ToString());
@@ -1974,5 +2181,36 @@ namespace FireWallet
AddBatch(domain, "RENEW");
}
}
private void githubToolStripMenuItem_Click(object sender, EventArgs e)
{
// Open the GitHub page
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "https://github.com/Nathanwoodburn/FireWallet/",
UseShellExecute = true
};
Process.Start(psi);
}
private void websiteToolStripMenuItem_Click(object sender, EventArgs e)
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "https://firewallet",
UseShellExecute = true
};
Process.Start(psi);
}
private void supportDiscordServerToolStripMenuItem_Click(object sender, EventArgs e)
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "https://l.woodburn.au/discord",
UseShellExecute = true
};
Process.Start(psi);
}
}
}

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

@@ -79,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)
@@ -136,8 +136,6 @@ namespace FireWallet
panelOutputs.Controls.Add(PanelOutput);
}
panelInputs.Visible = true;
panelOutputs.Visible = true;
}

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:{D85E3D97-B8F8-4212-9488-A48CF16CCF68}"
"PackageCode" = "8:{D2DCB865-F096-4420-AE54-579B6159A7CF}"
"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.7"
"ProductVersion" = "8:3.0"
"Manufacturer" = "8:Nathan.Woodburn/"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:https://l.woodburn.au/discord"

View File

@@ -134,6 +134,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 +151,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}