76 Commits

Author SHA1 Message Date
de7109eddc main: Added some improvements to hip02 addresses with trailing whitespace 2023-06-18 19:58:43 +10:00
1a98a6a1c6 main: Add option to set custom hip 02 ip and port 2023-06-18 19:42:05 +10:00
859562ac22 splash: Don't require top most 2023-06-18 19:41:26 +10:00
0a5412478c main: Cleaned up code and set splash to close after node connected
- Splash will not close anymore until Node is started and connected if internal HSD running.
- Splash will not close until after 4 seconds if external HSD running
2023-06-17 15:24:13 +10:00
90cc614ebf main: Updated theme dropdown and added new menu item for other projects.
- Changed foreach loop to update the foreground and background colors of ToolStripDropDownItems
- Added a new menu item "Other Projects" to the Help dropdown menu
- Created a new event handler method for the "Other Projects" menu item click action
2023-06-17 13:47:47 +10:00
a024ce7afc readme: Added installation dependencies
- Added instructions for installing .net desktop
- Added instructions for installing Node, NPM, and git
2023-06-16 11:20:48 +10:00
88ee50f4a6 main: Dependencies install links 2023-06-15 22:56:35 +10:00
23cbace1ea package: Increased version 2023-06-15 22:28:51 +10:00
6894e9c079 main: Fixed installation of hsd 2023-06-15 22:21:12 +10:00
95d0498672 main: cleaned up code 2023-06-15 22:01:32 +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
c7184be5ef main: Fixed installer problem (need to increase file version number) 2023-06-12 21:55:43 +10:00
b934ba2184 Added TXWindow 2023-06-12 21:36:07 +10:00
43a52cc029 tx: Added name to outputs 2023-06-12 21:35:39 +10:00
092e30799b main: Added TX windows to open and view txs in 2023-06-12 21:03:54 +10:00
54c5ccb555 main: Fixed bug with domain stats not being found 2023-06-12 14:53:07 +10:00
879f74f2bc installer: increased version number 2023-06-12 14:34:16 +10:00
41fa569563 main: updated no domains found error message 2023-06-12 14:27:36 +10:00
f4900cf9d6 main: Added reveal and renew all buttons 2023-06-12 14:23:02 +10:00
72be43e16d batch: Added error description to addresses exceed lookahead 2023-06-12 13:34:33 +10:00
c94bc8dcda batch: Added import any file type 2023-06-11 13:28:47 +10:00
145047b614 main: Fixed names page having errors when a domain is in auction 2023-06-11 13:28:35 +10:00
21ef8b2139 domain: Fixed single renews 2023-06-11 13:28:16 +10:00
860000bea8 main: Added checks for login without HSD connected 2023-06-11 12:45:02 +10:00
91c90136c1 readme: Added install video 2023-06-10 15:29:03 +10:00
e93ce03d50 install: Added new .msi installer for easier installation 2023-06-10 14:55:36 +10:00
520fe20051 docs: Added some debugging information 2023-06-10 13:42:52 +10:00
1b41b72193 Merge remote-tracking branch 'origin/master' 2023-06-10 13:20:29 +10:00
1d2597e1e7 readme: Added settings information
- Added information about the different settings files used in FireWallet
- Included details on what each file stores and how to access them
2023-06-10 13:20:24 +10:00
8aaf871bdf README: Added settings information
- Added information about the different settings files used in FireWallet
- Included details on what each file stores and how to access them
2023-06-10 13:20:12 +10:00
2e6f38d832 main: Added API key regex match 2023-06-10 12:50:28 +10:00
10662f5910 main: Added error checking in new cold wallet creation 2023-06-10 12:09:37 +10:00
7388710704 main: Added bug fixes for new installs 2023-06-09 23:43:50 +10:00
92bef9ef5d main: Added ledger verification for receive address 2023-06-09 17:28:51 +10:00
03a6b4d6da main: Require HSD API key 2023-06-09 16:09:19 +10:00
1a71329e6a readme: Added HSD info 2023-06-09 16:04:32 +10:00
c2990afed3 main: Added option to run HSD internally 2023-06-09 16:02:16 +10:00
28 changed files with 3557 additions and 513 deletions

View File

@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33723.286
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FireWallet", "FireWallet\FireWallet.csproj", "{14F28C5A-34CC-4FE0-8C8B-35C9A60704BC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FireWallet", "FireWallet\FireWallet.csproj", "{14F28C5A-34CC-4FE0-8C8B-35C9A60704BC}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "FireWalletSetup", "FireWalletSetup\FireWalletSetup.vdproj", "{D1751AFE-92C3-4C7E-B5E1-D1D6420A30EA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,8 @@ Global
{14F28C5A-34CC-4FE0-8C8B-35C9A60704BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14F28C5A-34CC-4FE0-8C8B-35C9A60704BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14F28C5A-34CC-4FE0-8C8B-35C9A60704BC}.Release|Any CPU.Build.0 = Release|Any CPU
{D1751AFE-92C3-4C7E-B5E1-D1D6420A30EA}.Debug|Any CPU.ActiveCfg = Debug
{D1751AFE-92C3-4C7E-B5E1-D1D6420A30EA}.Release|Any CPU.ActiveCfg = Release
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,5 +1,6 @@
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Principal;
@@ -464,7 +465,7 @@ namespace FireWallet
HttpClient httpClient = new HttpClient();
private async void buttonSend_Click(object sender, EventArgs e)
{
if (!mainForm.watchOnly)
if (!mainForm.WatchOnly)
{
string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]";
string content = "{\"method\": \"sendbatch\",\"params\":[ " + batchTX + "]}";
@@ -484,16 +485,30 @@ namespace FireWallet
{
AddLog("Error: ");
AddLog(jObject["error"].ToString());
NotifyForm notifyForm = new NotifyForm("Error: \n" + jObject["error"].ToString());
notifyForm.ShowDialog();
notifyForm.Dispose();
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;
}
JObject result = JObject.Parse(jObject["result"].ToString());
string hash = result["hash"].ToString();
AddLog("Batch sent with hash: " + hash);
NotifyForm notifyForm2 = new NotifyForm("Batch sent\nThis might take a while to mine.", "Explorer", mainForm.userSettings["explorer-tx"] + hash);
NotifyForm notifyForm2 = new NotifyForm("Batch sent\nThis might take a while to mine.", "Explorer", mainForm.UserSettings["explorer-tx"] + hash);
notifyForm2.ShowDialog();
notifyForm2.Dispose();
this.Close();
@@ -523,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();
@@ -543,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
@@ -567,7 +578,7 @@ namespace FireWallet
if (output.Contains("Submitted TXID"))
{
string hash = output.Substring(output.IndexOf("Submitted TXID") + 16, 64);
string link = mainForm.userSettings["explorer-tx"] + hash;
string link = mainForm.UserSettings["explorer-tx"] + hash;
NotifyForm notifySuccess = new NotifyForm("Transaction Sent\nThis transaction could take up to 20 minutes to mine",
"Explorer", link);
notifySuccess.ShowDialog();
@@ -575,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();
@@ -621,21 +634,49 @@ namespace FireWallet
private void buttonImport_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "CSV File|*.csv|TXT File|*.txt";
openFileDialog.Filter = "All Files|*.*";
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];
@@ -643,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();
}
}
@@ -717,10 +739,10 @@ namespace FireWallet
/// <returns></returns>
private async Task<string> APIPost(string path, bool wallet, string content)
{
string key = mainForm.nodeSettings["Key"];
string ip = mainForm.nodeSettings["IP"];
string key = mainForm.NodeSettings["Key"];
string ip = mainForm.NodeSettings["IP"];
string port = "1203";
if (mainForm.network == 1)
if (mainForm.HSDNetwork == 1)
{
port = "1303";
}

View File

@@ -27,7 +27,7 @@ namespace FireWallet
InitializeComponent();
this.domain = domain;
this.mainForm = mainForm;
nodeSettings = mainForm.nodeSettings;
nodeSettings = mainForm.NodeSettings;
cancel = true;
this.Text = domain + "/ DNS | FireWallet";
@@ -439,7 +439,7 @@ namespace FireWallet
string key = nodeSettings["Key"];
string ip = nodeSettings["IP"];
string port = "1203";
if (mainForm.network == 1)
if (mainForm.HSDNetwork == 1)
{
port = "1303";
}
@@ -478,7 +478,7 @@ namespace FireWallet
string ip = nodeSettings["IP"];
string port = "1203";
if (mainForm.network == 1)
if (mainForm.HSDNetwork == 1)
{
port = "1303";
}

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>();
@@ -230,7 +157,7 @@ namespace FireWallet
network = Convert.ToInt32(nodeSettings["Network"]);
GetName();
if (mainForm.watchOnly)
if (mainForm.WatchOnly)
{
buttonActionMain.Enabled = false; // Only allow sending in batches for ledger
}
@@ -330,6 +257,14 @@ namespace FireWallet
{
labelStatusMain.Text = "Error";
}
if (labelStatusReserved.Text == "True")
{
buttonActionAlt.Hide();
buttonActionMain.Hide();
groupBoxAction.Text = "Reserved";
}
}
catch (Exception ex)
{
@@ -771,9 +706,6 @@ namespace FireWallet
}
else if (state == "REVEAL")
{
decimal bid = Convert.ToDecimal(textBoxBid.Text);
decimal blind = Convert.ToDecimal(textBoxBlind.Text);
decimal lockup = bid + blind;
string content = "{\"method\": \"sendreveal\", \"params\": [\"" + domain + "\"]}";
string response = await APIPost("", true, content);
@@ -807,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,6 +12,7 @@
<PackageIcon>HSDBatcher.png</PackageIcon>
<RepositoryUrl>https://github.com/Nathanwoodburn/FireWallet</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>3.1</Version>
</PropertyGroup>
<ItemGroup>
@@ -26,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>
@@ -36,6 +38,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
@@ -45,4 +52,11 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -39,7 +39,12 @@ namespace FireWallet
toolStripStatusLabelNetwork = new ToolStripStatusLabel();
toolStripStatusLabelstatus = new ToolStripStatusLabel();
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();
@@ -58,6 +63,7 @@ namespace FireWallet
buttonNavSend = new Button();
buttonNavPortfolio = new Button();
panelPortfolio = new Panel();
buttonRevealAll = new Button();
groupBoxTransactions = new GroupBox();
groupBoxinfo = new GroupBox();
labelPendingCount = new Label();
@@ -67,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();
@@ -79,12 +87,17 @@ namespace FireWallet
labelSendingAmount = new Label();
labelSendingTo = new Label();
labelSendPrompt = new Label();
labelHIPArrow = new Label();
panelRecieve = new Panel();
buttonAddressVerify = new Button();
pictureBoxReceiveQR = new PictureBox();
labelReceive2 = new Label();
textBoxReceiveAddress = new TextBox();
labelReceive1 = new Label();
panelDomains = new Panel();
labelDomainSort = new Label();
comboBoxDomainSort = new ComboBox();
buttonExportDomains = new Button();
groupBoxDomains = new GroupBox();
panelDomainList = new Panel();
labelDomainSearch = new Label();
@@ -111,7 +124,8 @@ namespace FireWallet
textBoxExAddr = new TextBox();
labelSettings4 = new Label();
textBoxExTX = new TextBox();
toolStripStatusLabelLedger = new ToolStripStatusLabel();
toolStripSeparator1 = new ToolStripSeparator();
otherProjectsToolStripMenuItem = new ToolStripMenuItem();
statusStripmain.SuspendLayout();
panelaccount.SuspendLayout();
groupBoxaccount.SuspendLayout();
@@ -135,7 +149,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);
@@ -167,6 +181,14 @@ namespace FireWallet
toolStripStatusLabelaccount.Size = new Size(55, 17);
toolStripStatusLabelaccount.Text = "Account:";
//
// toolStripStatusLabelLedger
//
toolStripStatusLabelLedger.Margin = new Padding(50, 3, 50, 2);
toolStripStatusLabelLedger.Name = "toolStripStatusLabelLedger";
toolStripStatusLabelLedger.Size = new Size(71, 17);
toolStripStatusLabelLedger.Text = "Cold Wallet:";
toolStripStatusLabelLedger.Visible = false;
//
// toolStripSplitButtonlogout
//
toolStripSplitButtonlogout.DisplayStyle = ToolStripItemDisplayStyle.Text;
@@ -178,6 +200,39 @@ namespace FireWallet
toolStripSplitButtonlogout.Visible = false;
toolStripSplitButtonlogout.ButtonClick += Logout;
//
// toolStripDropDownButtonHelp
//
toolStripDropDownButtonHelp.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripDropDownButtonHelp.DropDownItems.AddRange(new ToolStripItem[] { githubToolStripMenuItem, websiteToolStripMenuItem, supportDiscordServerToolStripMenuItem, toolStripSeparator1, otherProjectsToolStripMenuItem });
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;
@@ -378,15 +433,28 @@ namespace FireWallet
//
// panelPortfolio
//
panelPortfolio.Controls.Add(buttonRevealAll);
panelPortfolio.Controls.Add(groupBoxTransactions);
panelPortfolio.Controls.Add(groupBoxinfo);
panelPortfolio.Controls.Add(groupBoxbalance);
panelPortfolio.Location = new Point(1085, 47);
panelPortfolio.Location = new Point(1065, 80);
panelPortfolio.Name = "panelPortfolio";
panelPortfolio.Size = new Size(956, 538);
panelPortfolio.TabIndex = 7;
panelPortfolio.Visible = false;
//
// buttonRevealAll
//
buttonRevealAll.FlatStyle = FlatStyle.Flat;
buttonRevealAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonRevealAll.Location = new Point(537, 12);
buttonRevealAll.Name = "buttonRevealAll";
buttonRevealAll.Size = new Size(89, 44);
buttonRevealAll.TabIndex = 9;
buttonRevealAll.Text = "Reveal All";
buttonRevealAll.UseVisualStyleBackColor = true;
buttonRevealAll.Click += buttonRevealAll_Click;
//
// groupBoxTransactions
//
groupBoxTransactions.Dock = DockStyle.Bottom;
@@ -481,8 +549,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);
@@ -494,12 +575,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;
@@ -542,11 +634,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
@@ -617,18 +709,43 @@ 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);
panelRecieve.Controls.Add(pictureBoxReceiveQR);
panelRecieve.Controls.Add(labelReceive2);
panelRecieve.Controls.Add(textBoxReceiveAddress);
panelRecieve.Controls.Add(labelReceive1);
panelRecieve.Location = new Point(1057, 62);
panelRecieve.Location = new Point(1140, 24);
panelRecieve.Name = "panelRecieve";
panelRecieve.Size = new Size(995, 523);
panelRecieve.TabIndex = 17;
panelRecieve.Visible = false;
//
// buttonAddressVerify
//
buttonAddressVerify.FlatStyle = FlatStyle.Flat;
buttonAddressVerify.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonAddressVerify.Location = new Point(769, 110);
buttonAddressVerify.Name = "buttonAddressVerify";
buttonAddressVerify.Size = new Size(126, 32);
buttonAddressVerify.TabIndex = 21;
buttonAddressVerify.Text = "Create && Verify";
buttonAddressVerify.UseVisualStyleBackColor = true;
buttonAddressVerify.Visible = false;
buttonAddressVerify.Click += buttonAddressVerify_Click;
//
// pictureBoxReceiveQR
//
pictureBoxReceiveQR.Location = new Point(391, 190);
@@ -670,15 +787,54 @@ 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(1129, 22);
panelDomains.Location = new Point(120, 48);
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;
buttonExportDomains.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonExportDomains.Location = new Point(351, 9);
buttonExportDomains.Name = "buttonExportDomains";
buttonExportDomains.Size = new Size(102, 32);
buttonExportDomains.TabIndex = 3;
buttonExportDomains.Text = "Export";
buttonExportDomains.UseVisualStyleBackColor = true;
buttonExportDomains.Click += export_Click;
//
// groupBoxDomains
//
groupBoxDomains.Controls.Add(panelDomainList);
@@ -727,7 +883,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(121, 21);
panelSettings.Location = new Point(1065, 51);
panelSettings.Name = "panelSettings";
panelSettings.Size = new Size(930, 550);
panelSettings.TabIndex = 19;
@@ -937,28 +1093,34 @@ namespace FireWallet
textBoxExTX.Size = new Size(307, 29);
textBoxExTX.TabIndex = 1;
//
// toolStripStatusLabelLedger
// toolStripSeparator1
//
toolStripStatusLabelLedger.Margin = new Padding(50, 3, 50, 2);
toolStripStatusLabelLedger.Name = "toolStripStatusLabelLedger";
toolStripStatusLabelLedger.Size = new Size(71, 17);
toolStripStatusLabelLedger.Text = "Cold Wallet:";
toolStripSeparator1.Name = "toolStripSeparator1";
toolStripSeparator1.Size = new Size(191, 6);
//
// otherProjectsToolStripMenuItem
//
otherProjectsToolStripMenuItem.Name = "otherProjectsToolStripMenuItem";
otherProjectsToolStripMenuItem.Size = new Size(194, 22);
otherProjectsToolStripMenuItem.Text = "Other Projects";
otherProjectsToolStripMenuItem.Click += otherProjectsToolStripMenuItem_Click;
//
// MainForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1152, 575);
Controls.Add(panelSettings);
Controls.Add(panelDomains);
Controls.Add(panelRecieve);
Controls.Add(panelSend);
Controls.Add(panelPortfolio);
Controls.Add(panelNav);
Controls.Add(panelSettings);
Controls.Add(panelaccount);
Controls.Add(panelPortfolio);
Controls.Add(panelRecieve);
Controls.Add(panelNav);
Controls.Add(statusStripmain);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "MainForm";
Opacity = 0D;
Text = "FireWallet";
FormClosing += MainForm_Closing;
Load += MainForm_Load;
@@ -1074,5 +1236,19 @@ namespace FireWallet
private GroupBox groupBoxSettingsWallet;
private Button buttonSettingsRescan;
private ToolStripStatusLabel toolStripStatusLabelLedger;
private Button buttonAddressVerify;
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 ToolStripSeparator toolStripSeparator1;
private ToolStripMenuItem otherProjectsToolStripMenuItem;
}
}

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

@@ -104,7 +104,6 @@
//
// buttonCold
//
buttonCold.Enabled = false;
buttonCold.FlatStyle = FlatStyle.Flat;
buttonCold.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonCold.Location = new Point(147, 239);

View File

@@ -2,9 +2,11 @@
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.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -25,7 +27,7 @@ namespace FireWallet
private void NewAccountForm_Load(object sender, EventArgs e)
{
page = 0;
Dictionary<string, string> theme = mainForm.theme;
Dictionary<string, string> theme = mainForm.Theme;
this.BackColor = ColorTranslator.FromHtml(theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(theme["foreground"]);
foreach (Control c in Controls)
@@ -59,9 +61,50 @@ namespace FireWallet
groupBoxNew.Text = "Import Wallet";
}
private void buttonCold_Click(object sender, EventArgs e)
private async void buttonCold_Click(object sender, EventArgs e)
{
// TODO - Cold wallet
if (!Directory.Exists(mainForm.dir + "hsd-ledger"))
{
if (mainForm.CheckNodeInstalled() == false)
{
mainForm.AddLog("Node not installed");
NotifyForm notify1 = new NotifyForm("Node not installed\nPlease install it to use Ledger");
notify1.ShowDialog();
notify1.Dispose();
return;
}
mainForm.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 = mainForm.dir + "hsd-ledger";
mainForm.CloneRepository(repositoryUrl, destinationPath);
Notifyinstall.CloseNotification();
Notifyinstall.Dispose();
}
catch (Exception ex)
{
NotifyForm notifyError = new NotifyForm("Error installing hsd-ledger\n" + ex.Message);
mainForm.AddLog(ex.Message);
notifyError.ShowDialog();
notifyError.Dispose();
return;
}
}
// Import HSD Wallet
groupBoxNew.Show();
groupBoxNew.Text = "Import Ledger";
buttonNext.Show();
page = 4;
}
private void textBoxNewName_TextChanged(object sender, EventArgs e)
@@ -136,7 +179,7 @@ namespace FireWallet
// Create new wallet
buttonNext.Enabled = false;
string path = "wallet/" + textBoxNewName.Text;
string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text +"\"}";
string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\"}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
@@ -152,15 +195,58 @@ namespace FireWallet
notify2.Dispose();
this.Close();
}
else if (page == 4)
{
try
{
// Import Ledger
buttonNext.Enabled = false;
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 = mainForm.dir + "hsd-ledger/bin/hsd-ledger createwallet " + textBoxNewPass1.Text + " --api-key " + mainForm.NodeSettings["Key"];
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();
mainForm.AddLog(outputBuilder.ToString());
}
catch (Exception ex)
{
mainForm.AddLog(ex.Message);
NotifyForm notify = new NotifyForm("Error importing wallet\n" + ex.Message);
notify.ShowDialog();
notify.Dispose();
this.Close();
return;
}
}
}
HttpClient httpClient = new HttpClient();
private async Task<string> APIPut(string path, bool wallet, string content)
{
string key = mainForm.nodeSettings["Key"];
string ip = mainForm.nodeSettings["IP"];
string key = mainForm.NodeSettings["Key"];
string ip = mainForm.NodeSettings["IP"];
string port = "1203";
if (mainForm.network == 1)
if (mainForm.HSDNetwork == 1)
{
port = "1303";
}
@@ -170,22 +256,28 @@ 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);
// Send request
HttpResponseMessage resp = await httpClient.SendAsync(req);
try
{
resp.EnsureSuccessStatusCode();
// Send request
HttpResponseMessage resp = await httpClient.SendAsync(req);
if (resp.IsSuccessStatusCode)
{
return await resp.Content.ReadAsStringAsync();
} else
{
mainForm.AddLog("Put Error: " + await resp.Content.ReadAsStringAsync());
return "Error";
}
}
catch (Exception ex)
{
mainForm.AddLog("Put Error: " + ex.Message);
mainForm.AddLog(await resp.Content.ReadAsStringAsync());
return "Error";
}
return await resp.Content.ReadAsStringAsync();
}
}
}

View File

@@ -36,6 +36,7 @@ namespace FireWallet
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NodeForm));
labelWelcome = new Label();
groupBoxNode = new GroupBox();
checkBoxRunHSD = new CheckBox();
labelNodeStatus = new Label();
comboBoxNodeNetwork = new ComboBox();
buttonSave = new Button();
@@ -61,6 +62,7 @@ namespace FireWallet
//
// groupBoxNode
//
groupBoxNode.Controls.Add(checkBoxRunHSD);
groupBoxNode.Controls.Add(labelNodeStatus);
groupBoxNode.Controls.Add(comboBoxNodeNetwork);
groupBoxNode.Controls.Add(buttonSave);
@@ -77,6 +79,16 @@ namespace FireWallet
groupBoxNode.TabStop = false;
groupBoxNode.Text = "Node";
//
// checkBoxRunHSD
//
checkBoxRunHSD.AutoSize = true;
checkBoxRunHSD.Location = new Point(62, 100);
checkBoxRunHSD.Name = "checkBoxRunHSD";
checkBoxRunHSD.Size = new Size(304, 19);
checkBoxRunHSD.TabIndex = 10;
checkBoxRunHSD.Text = "Run HSD (use this if you don't want to run Bob/HSD)";
checkBoxRunHSD.UseVisualStyleBackColor = true;
//
// labelNodeStatus
//
labelNodeStatus.AutoSize = true;
@@ -193,5 +205,6 @@ namespace FireWallet
private Button buttonSave;
private ComboBox comboBoxNodeNetwork;
private Label labelNodeStatus;
private CheckBox checkBoxRunHSD;
}
}

View File

@@ -7,6 +7,7 @@ using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
@@ -278,18 +279,47 @@ namespace FireWallet
private void SaveSettings(object sender, EventArgs e)
{
buttonNodeTest.PerformClick();
if (labelNodeStatus.Text != "Node Connected")
if (textBoxNodeKey.Text == "")
{
NotifyForm notifyForm = new NotifyForm("Please enter a key");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
StreamWriter sw = new StreamWriter(dir + "node.txt");
sw.WriteLine("IP: " + textBoxNodeIP.Text);
sw.WriteLine("Network: " + comboBoxNodeNetwork.SelectedIndex);
sw.WriteLine("Key: " + textBoxNodeKey.Text);
sw.Dispose();
this.Close();
if (checkBoxRunHSD.Checked)
{
if (!Regex.IsMatch(textBoxNodeKey.Text, @"^[a-zA-Z0-9]+$"))
{
NotifyForm notifyForm = new NotifyForm("Please enter valid API key\nDo not use spaces or weird stuff");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
StreamWriter sw = new StreamWriter(dir + "node.txt");
sw.WriteLine("IP: " + textBoxNodeIP.Text);
sw.WriteLine("Network: " + comboBoxNodeNetwork.SelectedIndex);
sw.WriteLine("Key: " + textBoxNodeKey.Text);
sw.WriteLine("HSD: True");
sw.Dispose();
this.Close();
}
else
{
buttonNodeTest.PerformClick();
if (labelNodeStatus.Text != "Node Connected")
{
return;
}
StreamWriter sw = new StreamWriter(dir + "node.txt");
sw.WriteLine("IP: " + textBoxNodeIP.Text);
sw.WriteLine("Network: " + comboBoxNodeNetwork.SelectedIndex);
sw.WriteLine("Key: " + textBoxNodeKey.Text);
sw.Dispose();
this.Close();
}
}
}
}

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FireWallet.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.6.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
</SettingsFile>

View File

@@ -28,21 +28,13 @@
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SplashScreen));
timerSplashDelay = new System.Windows.Forms.Timer(components);
label1 = new Label();
pictureBox1 = new PictureBox();
label2 = new Label();
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
SuspendLayout();
//
// timerSplashDelay
//
timerSplashDelay.Enabled = true;
timerSplashDelay.Interval = 3000;
timerSplashDelay.Tick += timerSplashDelay_Tick;
//
// label1
//
label1.AutoSize = true;
@@ -91,7 +83,6 @@
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterScreen;
Text = "FireWallet";
TopMost = true;
FormClosing += SplashScreen_FormClosing;
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
ResumeLayout(false);
@@ -99,8 +90,6 @@
}
#endregion
private System.Windows.Forms.Timer timerSplashDelay;
private Label label1;
private PictureBox pictureBox1;
private Label label2;

View File

@@ -13,18 +13,12 @@ namespace FireWallet
{
public partial class SplashScreen : Form
{
public SplashScreen()
public SplashScreen(bool timer)
{
InitializeComponent();
close = false;
}
bool close;
private void timerSplashDelay_Tick(object sender, EventArgs e)
{
close = true;
this.Close();
}
private void SplashScreen_FormClosing(object sender, FormClosingEventArgs e)
{
if (!close)
@@ -32,6 +26,11 @@ namespace FireWallet
e.Cancel = true;
}
}
public void CloseSplash()
{
close = true;
this.Close();
}
private void label2_Click(object sender, EventArgs e)
{

View File

@@ -117,9 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timerSplashDelay.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>

132
FireWallet/TXForm.Designer.cs generated Normal file
View File

@@ -0,0 +1,132 @@
namespace FireWallet
{
partial class TXForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TXForm));
labelHash = new Label();
groupBoxInputs = new GroupBox();
groupBoxOutputs = new GroupBox();
buttonExplorer = new Button();
panelInputs = new Panel();
panelOutputs = new Panel();
groupBoxInputs.SuspendLayout();
groupBoxOutputs.SuspendLayout();
SuspendLayout();
//
// labelHash
//
labelHash.AutoSize = true;
labelHash.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
labelHash.Location = new Point(12, 9);
labelHash.Name = "labelHash";
labelHash.Size = new Size(48, 21);
labelHash.TabIndex = 0;
labelHash.Text = "Hash:";
//
// groupBoxInputs
//
groupBoxInputs.Controls.Add(panelInputs);
groupBoxInputs.Location = new Point(12, 60);
groupBoxInputs.Name = "groupBoxInputs";
groupBoxInputs.Size = new Size(277, 378);
groupBoxInputs.TabIndex = 1;
groupBoxInputs.TabStop = false;
groupBoxInputs.Text = "Inputs";
//
// groupBoxOutputs
//
groupBoxOutputs.Controls.Add(panelOutputs);
groupBoxOutputs.Location = new Point(295, 60);
groupBoxOutputs.Name = "groupBoxOutputs";
groupBoxOutputs.Size = new Size(493, 378);
groupBoxOutputs.TabIndex = 0;
groupBoxOutputs.TabStop = false;
groupBoxOutputs.Text = "Outputs";
//
// buttonExplorer
//
buttonExplorer.FlatStyle = FlatStyle.Flat;
buttonExplorer.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonExplorer.Location = new Point(699, 12);
buttonExplorer.Name = "buttonExplorer";
buttonExplorer.Size = new Size(89, 37);
buttonExplorer.TabIndex = 0;
buttonExplorer.Text = "Explorer";
buttonExplorer.UseVisualStyleBackColor = true;
buttonExplorer.Click += Explorer_Click;
//
// panelInputs
//
panelInputs.AutoScroll = true;
panelInputs.Dock = DockStyle.Fill;
panelInputs.Location = new Point(3, 19);
panelInputs.Name = "panelInputs";
panelInputs.Size = new Size(271, 356);
panelInputs.TabIndex = 0;
//
// panelOutputs
//
panelOutputs.AutoScroll = true;
panelOutputs.Dock = DockStyle.Fill;
panelOutputs.Location = new Point(3, 19);
panelOutputs.Name = "panelOutputs";
panelOutputs.Size = new Size(487, 356);
panelOutputs.TabIndex = 0;
//
// TXForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(buttonExplorer);
Controls.Add(groupBoxOutputs);
Controls.Add(groupBoxInputs);
Controls.Add(labelHash);
FormBorderStyle = FormBorderStyle.Fixed3D;
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
Name = "TXForm";
Text = "TXForm";
Load += TXForm_Load;
groupBoxInputs.ResumeLayout(false);
groupBoxOutputs.ResumeLayout(false);
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelHash;
private GroupBox groupBoxInputs;
private GroupBox groupBoxOutputs;
private Button buttonExplorer;
private Panel panelInputs;
private Panel panelOutputs;
}
}

154
FireWallet/TXForm.cs Normal file
View File

@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
namespace FireWallet
{
public partial class TXForm : Form
{
MainForm mainForm;
JObject tx;
string txid;
public TXForm(MainForm mainForm, string txid)
{
InitializeComponent();
// Theme
this.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]);
foreach (Control c in Controls)
{
mainForm.ThemeControl(c);
}
this.mainForm = mainForm;
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"];
foreach (JObject input in inputs)
{
Panel PanelInput = new Panel();
PanelInput.Size = new Size(panelInputs.Width - SystemInformation.VerticalScrollBarWidth - 10, 50);
PanelInput.Location = new Point(5, panelInputs.Controls.Count * 50);
PanelInput.BorderStyle = BorderStyle.FixedSingle;
Label address = new Label();
string addressString = input["address"].ToString().Substring(0,5) + "..." + input["address"].ToString().Substring(input["address"].ToString().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(input["value"].ToString())/1000000;
amount.Text = "Amount: " + value.ToString();
amount.Location = new Point(5, 25);
amount.AutoSize = true;
PanelInput.Controls.Add(amount);
if (input["path"].ToString() != "")
{
Label ownAddress = new Label();
ownAddress.Text = "Own Address";
ownAddress.Location = new Point(PanelInput.Width - 100, 5);
ownAddress.AutoSize = true;
PanelInput.Controls.Add(ownAddress);
}
panelInputs.Controls.Add(PanelInput);
}
panelInputs.Visible = true;
// For each output
JArray outputs = (JArray)tx["outputs"];
foreach (JObject output in outputs)
{
Panel PanelOutput = new Panel();
PanelOutput.Size = new Size(panelOutputs.Width - SystemInformation.VerticalScrollBarWidth - 10, 50);
PanelOutput.Location = new Point(5, panelOutputs.Controls.Count * 50);
PanelOutput.BorderStyle = BorderStyle.FixedSingle;
Label address = new Label();
string addressString = output["address"].ToString().Substring(0, 5) + "..." + output["address"].ToString().Substring(output["address"].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")
{
JArray items = (JArray)covenant["items"];
Label covenantLabel = new Label();
string namehash = items[0].ToString();
string content = "{\"method\": \"getnamebyhash\", \"params\": [\"" +namehash +"\"]}";
JObject name = JObject.Parse(await mainForm.APIPost("",false,content));
covenantLabel.Text = covenant["action"].ToString() + ": " + name["result"].ToString();
covenantLabel.Location = new Point(5, 25);
covenantLabel.AutoSize = true;
PanelOutput.Controls.Add(covenantLabel);
}
}
Label amount = new Label();
Decimal value = Decimal.Parse(output["value"].ToString()) / 1000000;
amount.Text = "Amount: " + value.ToString();
amount.Location = new Point(PanelOutput.Width - 100, 25);
amount.AutoSize = true;
PanelOutput.Controls.Add(amount);
if (output["path"].ToString() != "")
{
Label ownAddress = new Label();
ownAddress.Text = "Own Address";
ownAddress.Location = new Point(PanelOutput.Width - 100, 5);
ownAddress.AutoSize = true;
PanelOutput.Controls.Add(ownAddress);
}
panelOutputs.Controls.Add(PanelOutput);
}
panelOutputs.Visible = true;
}
private void Explorer_Click(object sender, EventArgs e)
{
// Open the transaction in a browser
string url = mainForm.UserSettings["explorer-tx"] + tx["hash"].ToString();
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = url,
UseShellExecute = true
};
Process.Start(psi);
}
}
}

587
FireWallet/TXForm.resx Normal file
View File

@@ -0,0 +1,587 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<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>
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==
</value>
</data>
</root>

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
@@ -23,18 +25,18 @@ namespace FireWallet
Domain = domain;
this.Text = "Transfer " + Domain + " | FireWallet";
label1.Text = "Transfer " + Domain;
if (MainForm.theme.ContainsKey("error"))
if (MainForm.Theme.ContainsKey("error"))
{
labelError.ForeColor = ColorTranslator.FromHtml(MainForm.theme["error"]);
labelError.ForeColor = ColorTranslator.FromHtml(MainForm.Theme["error"]);
}
if (MainForm.watchOnly)
if (MainForm.WatchOnly)
{
buttonTransfer.Enabled = false; // watch only wallet only batch
}
// Theme
this.BackColor = ColorTranslator.FromHtml(MainForm.theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(MainForm.theme["foreground"]);
this.BackColor = ColorTranslator.FromHtml(MainForm.Theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(MainForm.Theme["foreground"]);
foreach (Control c in Controls)
{
MainForm.ThemeControl(c);
@@ -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() != "")
@@ -68,7 +73,7 @@ namespace FireWallet
}
JObject result = JObject.Parse(APIresp["result"].ToString());
string hash = result["hash"].ToString();
string link = MainForm.userSettings["explorer-tx"] + hash;
string link = MainForm.UserSettings["explorer-tx"] + hash;
NotifyForm notifySuccess = new NotifyForm("Transaction Sent\nThis transaction could take up to 20 minutes to mine",
"Explorer", link);
notifySuccess.ShowDialog();
@@ -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

@@ -0,0 +1,797 @@
"DeployProject"
{
"VSVersion" = "3:800"
"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"
"IsWebType" = "8:FALSE"
"ProjectName" = "8:FireWalletSetup"
"LanguageId" = "3:1033"
"CodePage" = "3:1252"
"UILanguageId" = "3:1033"
"SccProjectName" = "8:"
"SccLocalPath" = "8:"
"SccAuxPath" = "8:"
"SccProvider" = "8:"
"Hierarchy"
{
"Entry"
{
"MsmKey" = "8:_04F4559CA8D64ECF91FCC8C907FEA44E"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_24448DEFADA9423B92D588F3CCFCE0BE"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_57B16B55588E41459D70F9475B14B4BB"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
}
"Configurations"
{
"Debug"
{
"DisplayName" = "8:Debug"
"IsDebugOnly" = "11:TRUE"
"IsReleaseOnly" = "11:FALSE"
"OutputFilename" = "8:Debug\\FireWalletSetup.msi"
"PackageFilesAs" = "3:2"
"PackageFileSize" = "3:-2147483648"
"CabType" = "3:1"
"Compression" = "3:2"
"SignOutput" = "11:FALSE"
"CertificateFile" = "8:"
"PrivateKeyFile" = "8:"
"TimeStampServer" = "8:"
"InstallerBootstrapper" = "3:2"
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
{
"Enabled" = "11:TRUE"
"PromptEnabled" = "11:TRUE"
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
"ComponentsUrl" = "8:"
"Items"
{
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
{
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
}
}
}
}
"Release"
{
"DisplayName" = "8:Release"
"IsDebugOnly" = "11:FALSE"
"IsReleaseOnly" = "11:TRUE"
"OutputFilename" = "8:Release\\FireWalletSetup.msi"
"PackageFilesAs" = "3:2"
"PackageFileSize" = "3:-2147483648"
"CabType" = "3:1"
"Compression" = "3:2"
"SignOutput" = "11:FALSE"
"CertificateFile" = "8:"
"PrivateKeyFile" = "8:"
"TimeStampServer" = "8:"
"InstallerBootstrapper" = "3:2"
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
{
"Enabled" = "11:TRUE"
"PromptEnabled" = "11:TRUE"
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
"ComponentsUrl" = "8:"
"Items"
{
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
{
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
}
}
}
}
}
"Deployable"
{
"CustomAction"
{
}
"DefaultFeature"
{
"Name" = "8:DefaultFeature"
"Title" = "8:"
"Description" = "8:"
}
"ExternalPersistence"
{
"LaunchCondition"
{
"{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_EFBFB4D93D6D4A0FBAC69F265F0E04DB"
{
"Name" = "8:.NET Core"
"Message" = "8:[VSDNETCOREMSG]"
"AllowLaterVersions" = "11:FALSE"
"InstallUrl" = "8:https://dotnet.microsoft.com/download/dotnet-core/[NetCoreVerMajorDotMinor]"
"IsNETCore" = "11:TRUE"
"Architecture" = "2:0"
"Runtime" = "2:0"
}
}
}
"File"
{
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_04F4559CA8D64ECF91FCC8C907FEA44E"
{
"SourcePath" = "8:..\\..\\..\\..\\Downloads\\FW.ico"
"TargetName" = "8:FW.ico"
"Tag" = "8:"
"Folder" = "8:_5E5E37B331014B2BBEB73878A5BF354B"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_57B16B55588E41459D70F9475B14B4BB"
{
"SourcePath" = "8:..\\..\\..\\..\\Downloads\\FWBanner.bmp"
"TargetName" = "8:FWBanner.bmp"
"Tag" = "8:"
"Folder" = "8:_5E5E37B331014B2BBEB73878A5BF354B"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
}
"FileType"
{
}
"Folder"
{
"{3C67513D-01DD-4637-8A68-80971EB9504F}:_5E5E37B331014B2BBEB73878A5BF354B"
{
"DefaultLocation" = "8:[ProgramFilesFolder]\\FireWallet"
"Name" = "8:#1925"
"AlwaysCreate" = "11:FALSE"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Property" = "8:TARGETDIR"
"Folders"
{
}
}
"{1525181F-901A-416C-8A58-119130FE478E}:_BCC2277C7F2A49D9859AB85BE80771EC"
{
"Name" = "8:#1916"
"AlwaysCreate" = "11:FALSE"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Property" = "8:DesktopFolder"
"Folders"
{
}
}
"{1525181F-901A-416C-8A58-119130FE478E}:_C825708961074F0AB407ADD664E1DFA7"
{
"Name" = "8:#1919"
"AlwaysCreate" = "11:FALSE"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Property" = "8:ProgramMenuFolder"
"Folders"
{
}
}
}
"LaunchCondition"
{
}
"Locator"
{
}
"MsiBootstrapper"
{
"LangId" = "3:1033"
"RequiresElevation" = "11:FALSE"
}
"Product"
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:FireWallet"
"ProductCode" = "8:{460D8F86-4FE9-4547-9B17-7E01ACBF9194}"
"PackageCode" = "8:{A6678F97-9CE8-4005-82AC-AB2D09A9DA27}"
"UpgradeCode" = "8:{0C86F725-6B01-4173-AA05-3F0EDF481362}"
"AspNetVersion" = "8:"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:3.1"
"Manufacturer" = "8:Nathan.Woodburn/"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:https://l.woodburn.au/discord"
"Title" = "8:FireWallet"
"Subject" = "8:"
"ARPCONTACT" = "8:Nathan.Woodburn/"
"Keywords" = "8:"
"ARPCOMMENTS" = "8:The Handshake wallet that is just Fire"
"ARPURLINFOABOUT" = "8:https://github.com/Nathanwoodburn/FireWallet"
"ARPPRODUCTICON" = "8:_04F4559CA8D64ECF91FCC8C907FEA44E"
"ARPIconIndex" = "3:0"
"SearchPath" = "8:"
"UseSystemSearchPath" = "11:TRUE"
"TargetPlatform" = "3:0"
"PreBuildEvent" = "8:"
"PostBuildEvent" = "8:"
"RunPostBuildEvent" = "3:0"
}
"Registry"
{
"HKLM"
{
"Keys"
{
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_5CDEC48EDB6148E1938060F809CCE1AA"
{
"Name" = "8:Software"
"Condition" = "8:"
"AlwaysCreate" = "11:FALSE"
"DeleteAtUninstall" = "11:FALSE"
"Transitive" = "11:FALSE"
"Keys"
{
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_01E845438BDD488C9229BED4A07565D8"
{
"Name" = "8:[Manufacturer]"
"Condition" = "8:"
"AlwaysCreate" = "11:FALSE"
"DeleteAtUninstall" = "11:FALSE"
"Transitive" = "11:FALSE"
"Keys"
{
}
"Values"
{
}
}
}
"Values"
{
}
}
}
}
"HKCU"
{
"Keys"
{
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_E241C5D914C447D98BB058FEDA6FB2E0"
{
"Name" = "8:Software"
"Condition" = "8:"
"AlwaysCreate" = "11:FALSE"
"DeleteAtUninstall" = "11:FALSE"
"Transitive" = "11:FALSE"
"Keys"
{
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_9056723452D74EEDA92F2BFD694C9C09"
{
"Name" = "8:[Manufacturer]"
"Condition" = "8:"
"AlwaysCreate" = "11:FALSE"
"DeleteAtUninstall" = "11:FALSE"
"Transitive" = "11:FALSE"
"Keys"
{
}
"Values"
{
}
}
}
"Values"
{
}
}
}
}
"HKCR"
{
"Keys"
{
}
}
"HKU"
{
"Keys"
{
}
}
"HKPU"
{
"Keys"
{
}
}
}
"Sequences"
{
}
"Shortcut"
{
"{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_77F1CD9C54DE4F0294C9C2C3DAD59446"
{
"Name" = "8:FireWallet"
"Arguments" = "8:"
"Description" = "8:The Handshake wallet that is just Fire"
"ShowCmd" = "3:1"
"IconIndex" = "3:0"
"Transitive" = "11:FALSE"
"Target" = "8:_24448DEFADA9423B92D588F3CCFCE0BE"
"Folder" = "8:_C825708961074F0AB407ADD664E1DFA7"
"WorkingFolder" = "8:_5E5E37B331014B2BBEB73878A5BF354B"
"Icon" = "8:_04F4559CA8D64ECF91FCC8C907FEA44E"
"Feature" = "8:"
}
}
"UserInterface"
{
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_324353D76F3C40A7AC383ECFFB7AD313"
{
"Name" = "8:#1901"
"Sequence" = "3:2"
"Attributes" = "3:2"
"Dialogs"
{
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9E8FABACA40B4AF19AC7837F6199E349"
{
"Sequence" = "3:100"
"DisplayName" = "8:Progress"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:0"
"UsePlugInResources" = "11:TRUE"
}
"ShowProgress"
{
"Name" = "8:ShowProgress"
"DisplayName" = "8:#1009"
"Description" = "8:#1109"
"Type" = "3:5"
"ContextData" = "8:1;True=1;False=0"
"Attributes" = "3:0"
"Setting" = "3:0"
"Value" = "3:1"
"DefaultValue" = "3:1"
"UsePlugInResources" = "11:TRUE"
}
}
}
}
}
"{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_32996AB03B5A4723B065CE209D7CB353"
{
"UseDynamicProperties" = "11:FALSE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim"
}
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_5F8B496BAA7C4A4A83CC46CE05F0536A"
{
"Name" = "8:#1900"
"Sequence" = "3:2"
"Attributes" = "3:1"
"Dialogs"
{
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A09B666A12A14C99B65048178A482B56"
{
"Sequence" = "3:300"
"DisplayName" = "8:Confirm Installation"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:0"
"UsePlugInResources" = "11:TRUE"
}
}
}
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B3830A4823DE445B8A66D38BC4EA17AD"
{
"Sequence" = "3:200"
"DisplayName" = "8:Installation Folder"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:0"
"UsePlugInResources" = "11:TRUE"
}
}
}
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F1DC457477AE4898BBA3BE9EADB3A338"
{
"Sequence" = "3:100"
"DisplayName" = "8:Welcome"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:2"
"Value" = "8:_57B16B55588E41459D70F9475B14B4BB"
"UsePlugInResources" = "11:TRUE"
}
"CopyrightWarning"
{
"Name" = "8:CopyrightWarning"
"DisplayName" = "8:#1002"
"Description" = "8:#1102"
"Type" = "3:3"
"ContextData" = "8:"
"Attributes" = "3:0"
"Setting" = "3:2"
"Value" = "8:WARNING: This computer program is experimental and is not guaranteed to be free of bugs. Please report any bugs to the Nathan or open an issue on the GitHub repository."
"DefaultValue" = "8:#1202"
"UsePlugInResources" = "11:TRUE"
}
"Welcome"
{
"Name" = "8:Welcome"
"DisplayName" = "8:#1003"
"Description" = "8:#1103"
"Type" = "3:3"
"ContextData" = "8:"
"Attributes" = "3:0"
"Setting" = "3:1"
"Value" = "8:#1203"
"DefaultValue" = "8:#1203"
"UsePlugInResources" = "11:TRUE"
}
}
}
}
}
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_815C979C89AA4703BA731134B3DF354D"
{
"Name" = "8:#1902"
"Sequence" = "3:2"
"Attributes" = "3:3"
"Dialogs"
{
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D48757B8F9644017B6E349A2ADFC4926"
{
"Sequence" = "3:100"
"DisplayName" = "8:Finished"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:0"
"UsePlugInResources" = "11:TRUE"
}
}
}
}
}
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_8F9198D340754DEE9FFB73D19BBC990E"
{
"Name" = "8:#1902"
"Sequence" = "3:1"
"Attributes" = "3:3"
"Dialogs"
{
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_1B933693E12C4BD5B3C54B519C9B1F44"
{
"Sequence" = "3:100"
"DisplayName" = "8:Finished"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:2"
"Value" = "8:_57B16B55588E41459D70F9475B14B4BB"
"UsePlugInResources" = "11:TRUE"
}
"UpdateText"
{
"Name" = "8:UpdateText"
"DisplayName" = "8:#1058"
"Description" = "8:#1158"
"Type" = "3:15"
"ContextData" = "8:"
"Attributes" = "3:0"
"Setting" = "3:1"
"Value" = "8:#1258"
"DefaultValue" = "8:#1258"
"UsePlugInResources" = "11:TRUE"
}
}
}
}
}
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B6C7BA0AF8C2424AABEAFBFD45FF0FE5"
{
"Name" = "8:#1901"
"Sequence" = "3:1"
"Attributes" = "3:2"
"Dialogs"
{
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_52696058E87E4D62B45AABE61847F970"
{
"Sequence" = "3:100"
"DisplayName" = "8:Progress"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:2"
"Value" = "8:_57B16B55588E41459D70F9475B14B4BB"
"UsePlugInResources" = "11:TRUE"
}
"ShowProgress"
{
"Name" = "8:ShowProgress"
"DisplayName" = "8:#1009"
"Description" = "8:#1109"
"Type" = "3:5"
"ContextData" = "8:1;True=1;False=0"
"Attributes" = "3:0"
"Setting" = "3:0"
"Value" = "3:1"
"DefaultValue" = "3:1"
"UsePlugInResources" = "11:TRUE"
}
}
}
}
}
"{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_DAC87040C23F42E5A149D5258B972E5E"
{
"UseDynamicProperties" = "11:FALSE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim"
}
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E63D340D36A543A8BBF49B7BC9395B62"
{
"Name" = "8:#1900"
"Sequence" = "3:1"
"Attributes" = "3:1"
"Dialogs"
{
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_0315D52EA80A47BC987BE0887D3DBDEA"
{
"Sequence" = "3:100"
"DisplayName" = "8:Welcome"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:2"
"Value" = "8:_57B16B55588E41459D70F9475B14B4BB"
"UsePlugInResources" = "11:TRUE"
}
"CopyrightWarning"
{
"Name" = "8:CopyrightWarning"
"DisplayName" = "8:#1002"
"Description" = "8:#1102"
"Type" = "3:3"
"ContextData" = "8:"
"Attributes" = "3:0"
"Setting" = "3:2"
"Value" = "8:WARNING: This computer program is experimental and is not guaranteed to be free of bugs. Please report any bugs to the Nathan or open an issue on the GitHub repository."
"DefaultValue" = "8:#1202"
"UsePlugInResources" = "11:TRUE"
}
"Welcome"
{
"Name" = "8:Welcome"
"DisplayName" = "8:#1003"
"Description" = "8:#1103"
"Type" = "3:3"
"ContextData" = "8:"
"Attributes" = "3:0"
"Setting" = "3:1"
"Value" = "8:#1203"
"DefaultValue" = "8:#1203"
"UsePlugInResources" = "11:TRUE"
}
}
}
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7674CF69E98F4233B169B0E10CB27009"
{
"Sequence" = "3:200"
"DisplayName" = "8:Installation Folder"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:2"
"Value" = "8:_57B16B55588E41459D70F9475B14B4BB"
"UsePlugInResources" = "11:TRUE"
}
"InstallAllUsersVisible"
{
"Name" = "8:InstallAllUsersVisible"
"DisplayName" = "8:#1059"
"Description" = "8:#1159"
"Type" = "3:5"
"ContextData" = "8:1;True=1;False=0"
"Attributes" = "3:0"
"Setting" = "3:0"
"Value" = "3:0"
"DefaultValue" = "3:1"
"UsePlugInResources" = "11:TRUE"
}
}
}
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E94A31E39D684EC09F27D5431F16531B"
{
"Sequence" = "3:300"
"DisplayName" = "8:Confirm Installation"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid"
"Properties"
{
"BannerBitmap"
{
"Name" = "8:BannerBitmap"
"DisplayName" = "8:#1001"
"Description" = "8:#1101"
"Type" = "3:8"
"ContextData" = "8:Bitmap"
"Attributes" = "3:4"
"Setting" = "3:2"
"Value" = "8:_57B16B55588E41459D70F9475B14B4BB"
"UsePlugInResources" = "11:TRUE"
}
}
}
}
}
}
"MergeModule"
{
}
"ProjectOutput"
{
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_24448DEFADA9423B92D588F3CCFCE0BE"
{
"SourcePath" = "8:..\\FireWallet\\obj\\Debug\\net6.0-windows\\apphost.exe"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_5E5E37B331014B2BBEB73878A5BF354B"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
"ProjectOutputGroupRegister" = "3:1"
"OutputConfiguration" = "8:"
"OutputGroupCanonicalName" = "8:PublishItems"
"OutputProjectGuid" = "8:{14F28C5A-34CC-4FE0-8C8B-35C9A60704BC}"
"ShowKeyOutput" = "11:TRUE"
"ExcludeFilters"
{
}
}
}
}
}

View File

@@ -2,8 +2,21 @@
Experimental wallet for Handshake chain
## Installation
### Dependencies
You will need .net desktop installed. You can download it from [here](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.18-windows-x64-installer).
You will also need Node, NPM, and git installed if you want to use the internal HSD or Ledger wallets.
[Git](https://git-scm.com/downloads)
[Node](https://nodejs.org/en/download/)
[NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
### From Releases
You can install the latest release from [here](https://github.com/Nathanwoodburn/FireWallet/releases/).
Here are some videos showing how to install and use FireWallet:
Install with a running Bob wallet: https://cloud.woodburn.au/s/pS8e2oQDidrMJWx
Install with internal HSD: https://cloud.woodburn.au/s/trwd8TyxbDfqaxF (You NEED to have Node, NPM, and git installed to use internal HSD)
### Build from source
You can build from source by cloning this repo.
You will need Visual Studio (recommend a recent version) and .net desktop development tools installed.
@@ -21,6 +34,10 @@ This password will be used to encrypt your wallet and to login to your wallet.
## First time setup
When you first open the wallet you will be prompted to set your node settings.
You can either connect to an existing HSD (or Bob) node or you can run your own node.
If you want to run your own node you should select the `Run HSD` option.
This will take a few minutes to download and install HSD.
You can get the API key from the HSD launch command or
in Bob wallet under settings > Wallet > API key.
If you change this key in HSD or Bob you will need to update it in FireWallet.
@@ -51,6 +68,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.
@@ -95,6 +115,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
@@ -111,3 +133,41 @@ You can use a Ledger device to sign transactions.
You need to have Node, NPM, and git installed to use Ledger.
The Ledger components are not included in the app.
These will install when you first send HNS (not domains) from a Ledger.
# Settings
FireWallet uses a few different settings files.
They are stored in `%appdata%\FireWallet\` (`C:\Users\{username}\AppData\Roaming\FireWallet\`)
## settings.txt
This file stores the user settings for the application.
## node.txt
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.
The `transparent-mode` key is used to enable or disable transparent modes.
There are 4 modes: `off` is disabled, `mica` is windows app style, `key` is to make 1 colour transparent, and `percent` is to set the opacity of the window.
## log.txt
This file stores the logs for 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.

19
debugging.md Normal file
View File

@@ -0,0 +1,19 @@
# Debugging Info
## App startup errors
## Node (HSD) errors
If you have selected to run the internal node you can check these steps to see if you can fix the issue.
1. Check the HSD directory in `%appdata%\FireWallet\` (`C:\Users\{username}\AppData\Roaming\FireWallet\HSD`)
2. Try running `npm install` in the HSD directory (could have failed in the install process)
3. Look in the HSD logs for errors in `C:\Users\{username}\.hsd\debug.log`
## Ledger errors
If you are having issues with Ledger you can check these steps to see if you can fix the issue.
1. Check the Ledger directory in `%appdata%\FireWallet\` (`C:\Users\{username}\AppData\Roaming\FireWallet\hsd-ledger`)
2. Try running `npm install` in the Ledger directory (could have failed in the install process)
3. Try running `node bin\hsd-ledger createaddress --api-key {api-key} -w {cold wallet name}` in the Ledger directory. This will get you to verify your address on the ledger device. If this fails you have some bigger issue.

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>');