Compare commits

...

91 Commits
v2.5 ... master

Author SHA1 Message Date
d0db49c334
feat: Add info on python3 firewallet and remove old error message 2024-07-17 18:23:00 +10:00
aca91a863b
Merge branch 'hotfix/passwordEscape' 2023-08-18 14:07:49 +10:00
2a6a708d70
Accounts: Fix password escape to allow quotes and backslash 2023-08-18 14:07:23 +10:00
8758a5fd5e
README: Added info on fixing batch bid bug 2023-08-07 16:32:19 +10:00
7af283a71e
README: Added warning about batch bids 2023-07-13 16:39:14 +10:00
a930385e26
README: Fixed spacing 2023-06-27 13:23:41 +10:00
3caff3b7c1
main: Reduced extra logging 2023-06-27 13:13:16 +10:00
e6d75533e3
README.md: Added thanks to designer and added info on the websitesection
- Added a "Thanks" section to acknowledge the designer of the logo and splash screen
- Added links to the website
2023-06-27 13:01:07 +10:00
7b51c62098
multisig: Removed excess logging 2023-06-27 12:44:18 +10:00
0306b78d34
Merge pull request #1 from Nathanwoodburn/multisig
Add multisig support
2023-06-27 12:30:16 +10:00
ac5cc3f82e
package: Cleaned up code and increased version number 2023-06-27 12:15:51 +10:00
c964aa0064
multisig: Added settings and cleaned up new account creation 2023-06-27 11:49:47 +10:00
fe7fc4cee9
multisig: Cleaned up code and added checks to not show >n signers 2023-06-26 21:44:11 +10:00
6cc6cd4a79
multisig: Disabled bulk actions and a set to reqiure batch
- Added condition to disable buttonActionMain when mainForm.multiSig is true

- Removed buttons (buttonRevealAll, buttonRedeemAll, and buttonSendAll) when WatchOnly or multiSig is true
- Added buttons (buttonAddressVerify) when WatchOnly is true
- Updated conditions for showing/hiding toolStripStatusLabelLedger and toolStripStatusLabelMultisig
2023-06-26 21:25:42 +10:00
f69f16df4a
multisig: Added multisig from batching 2023-06-26 21:21:55 +10:00
db5934bf4a
batch: Fixed batch form flashing when it imports 2023-06-26 21:21:03 +10:00
54d5c63db7
multisig: Finished signing for hot wallets 2023-06-26 18:48:12 +10:00
6da345e650
multisig: Added info on signers
Added variables to track the number of total signers, required signers and signed signatures. Also added code to get multisig information from transaction inputs and display it in the UI.
2023-06-26 18:13:08 +10:00
5be4f0d6e9
multisig: Added import tx 2023-06-26 16:21:05 +10:00
b1d21289ab
main: Initial send multisig to address 2023-06-26 16:20:54 +10:00
cefd2d18c7
main: Added multisig detect 2023-06-26 14:31:18 +10:00
d8efdb98f7
batch: Bring form to front after you add a new batch 2023-06-24 14:39:59 +10:00
eea79b92d4
main: Added HIP-02 to batch import transfers 2023-06-24 11:41:05 +10:00
ffd1372eca
transform: Updated HIP02 to use MainForm's task 2023-06-24 11:34:02 +10:00
cbf1bc3e38
main: Moved HIP02 lookup to its own task 2023-06-24 11:28:30 +10:00
843f824b2f
package: Increased version 2023-06-22 13:29:37 +10:00
71a04edc02
README.md: Added default settings to config file
- Added default settings for HideScreen and Timeout to the config file
- Users can modify these values in the file if needed
2023-06-22 13:26:58 +10:00
30c5690c24
main: Custom timeouts 2023-06-22 13:20:11 +10:00
af9327a1fa
main: Restart node if it hangs 2023-06-22 12:55:46 +10:00
07345d7f33
Merge branch 'newBranding' 2023-06-21 21:32:08 +10:00
d41c72faff
main: Added redeem and send all 2023-06-21 21:31:46 +10:00
a4a35ad62e
splash: Cleaned up code 2023-06-21 19:42:19 +10:00
9f0f7214e2
splash: Added splash screen fade in out 2023-06-21 19:38:20 +10:00
742cd9bafd
main: Initial new image 2023-06-21 17:57:52 +10:00
9f33c74bb0
main: Added Register support 2023-06-21 12:12:45 +10:00
8f241fc90a
main: Stop logging sending HNS unless errors 2023-06-20 12:39:51 +10:00
dc09194759
readme: Added info on donating straight to @firewallet 2023-06-20 12:11:44 +10:00
638a367029
package: Increased version 2023-06-20 11:58:51 +10:00
026849575d
readme: Removed warning about import UPDATE not working 2023-06-20 11:58:02 +10:00
d1a150114e
main: Updated batching and docs
- Updated example-configs/batch.txt with new DNS records
- Modified BatchForm.cs to handle new DNS record types
2023-06-20 11:57:33 +10:00
5d59bdee64
dns: Updated DNS record parsing and formatting
- Added support for new DNS record types
- Improved formatting of update records in BatchForm.cs
2023-06-20 11:43:39 +10:00
74548a22e2
main: Removed unused dependencies 2023-06-19 13:24:18 +10:00
ac2aa06888
main: Fixed resizing form 2023-06-19 11:31:43 +10:00
429cf0d67b
package: Increase version 2023-06-18 20:33:27 +10:00
38838096d6
readme: Added info on HIP-02 config 2023-06-18 20:28:08 +10:00
fae4bff32b
main: HIP-02 fix for Bob port
If Bob is the HSD FireWallet is connected to use the default Bob DNS resolver port
2023-06-18 20:25:27 +10:00
df8c675588
Merge branch 'hip02remote' 2023-06-18 20:10:31 +10:00
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
33 changed files with 5108 additions and 1502 deletions

View File

@ -1,12 +1,10 @@
using System.Data; using System.Data;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Net; using System.Net;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text; using System.Text;
using Microsoft.VisualBasic;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using ContentAlignment = System.Drawing.ContentAlignment;
using Point = System.Drawing.Point; using Point = System.Drawing.Point;
namespace FireWallet namespace FireWallet
@ -25,6 +23,13 @@ namespace FireWallet
this.mainForm = mainForm; this.mainForm = mainForm;
batches = new Batch[0]; batches = new Batch[0];
} }
public void bringToFront()
{
// Minimize this form and bring it back up
this.WindowState = FormWindowState.Minimized;
this.Show();
this.WindowState = FormWindowState.Normal;
}
public void AddBatch(string domain, string operation) public void AddBatch(string domain, string operation)
{ {
if (operation == "BID") return; if (operation == "BID") return;
@ -60,7 +65,7 @@ namespace FireWallet
List<Batch> temp = new List<Batch>(); List<Batch> temp = new List<Batch>();
foreach (Batch batch in batches) foreach (Batch batch in batches)
{ {
if (batch.domain != domain && batch.method != operation) if (batch.domain != domain || batch.method != operation)
{ {
temp.Add(batch); temp.Add(batch);
} }
@ -72,7 +77,6 @@ namespace FireWallet
tx.Controls.Add(deleteTX); tx.Controls.Add(deleteTX);
panelTXs.Controls.Add(tx); panelTXs.Controls.Add(tx);
UpdateTheme();
} }
public void AddBatch(string domain, string operation, decimal bid, decimal lockup) public void AddBatch(string domain, string operation, decimal bid, decimal lockup)
{ {
@ -124,7 +128,7 @@ namespace FireWallet
List<Batch> temp = new List<Batch>(); List<Batch> temp = new List<Batch>();
foreach (Batch batch in batches) foreach (Batch batch in batches)
{ {
if (batch.domain != domain && batch.method != operation) if (batch.domain != domain || batch.method != operation)
{ {
temp.Add(batch); temp.Add(batch);
} }
@ -136,7 +140,6 @@ namespace FireWallet
tx.Controls.Add(deleteTX); tx.Controls.Add(deleteTX);
panelTXs.Controls.Add(tx); panelTXs.Controls.Add(tx);
UpdateTheme();
} }
public void AddBatch(string domain, string operation, string toAddress) public void AddBatch(string domain, string operation, string toAddress)
{ {
@ -184,7 +187,7 @@ namespace FireWallet
List<Batch> temp = new List<Batch>(); List<Batch> temp = new List<Batch>();
foreach (Batch batch in batches) foreach (Batch batch in batches)
{ {
if (batch.domain != domain && batch.method != operation) if (batch.domain != domain || batch.method != operation)
{ {
temp.Add(batch); temp.Add(batch);
} }
@ -196,7 +199,6 @@ namespace FireWallet
tx.Controls.Add(deleteTX); tx.Controls.Add(deleteTX);
panelTXs.Controls.Add(tx); panelTXs.Controls.Add(tx);
UpdateTheme();
} }
public void AddBatch(string domain, string operation, DNS[] updateRecords) public void AddBatch(string domain, string operation, DNS[] updateRecords)
@ -240,7 +242,7 @@ namespace FireWallet
List<Batch> temp = new List<Batch>(); List<Batch> temp = new List<Batch>();
foreach (Batch batch in batches) foreach (Batch batch in batches)
{ {
if (batch.domain != domain && batch.method != operation) if (batch.domain != domain || batch.method != operation)
{ {
temp.Add(batch); temp.Add(batch);
} }
@ -252,7 +254,6 @@ namespace FireWallet
tx.Controls.Add(deleteTX); tx.Controls.Add(deleteTX);
panelTXs.Controls.Add(tx); panelTXs.Controls.Add(tx);
UpdateTheme();
} }
private void FixSpacing() private void FixSpacing()
@ -272,7 +273,7 @@ namespace FireWallet
} }
#endregion #endregion
#region Theming #region Theming
private void UpdateTheme() public void UpdateTheme()
{ {
// Check if file exists // Check if file exists
if (!Directory.Exists(dir)) if (!Directory.Exists(dir))
@ -315,7 +316,7 @@ namespace FireWallet
} }
applyTransparency(theme); applyTransparency(theme);
bringToFront();
} }
private void ThemeControl(Control c) private void ThemeControl(Control c)
{ {
@ -465,7 +466,7 @@ namespace FireWallet
HttpClient httpClient = new HttpClient(); HttpClient httpClient = new HttpClient();
private async void buttonSend_Click(object sender, EventArgs e) private async void buttonSend_Click(object sender, EventArgs e)
{ {
if (!mainForm.watchOnly) if (!mainForm.WatchOnly && !mainForm.multiSig)
{ {
string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]"; string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]";
string content = "{\"method\": \"sendbatch\",\"params\":[ " + batchTX + "]}"; string content = "{\"method\": \"sendbatch\",\"params\":[ " + batchTX + "]}";
@ -508,11 +509,63 @@ namespace FireWallet
JObject result = JObject.Parse(jObject["result"].ToString()); JObject result = JObject.Parse(jObject["result"].ToString());
string hash = result["hash"].ToString(); string hash = result["hash"].ToString();
AddLog("Batch sent with hash: " + hash); 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.ShowDialog();
notifyForm2.Dispose(); notifyForm2.Dispose();
this.Close(); this.Close();
} }
else if (mainForm.multiSig)
{
string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]";
string content = "{\"method\": \"createbatch\",\"params\":[ " + batchTX + "]}";
string responce = await APIPost("", true, content);
if (responce == "Error")
{
AddLog("Error sending batch");
NotifyForm notifyForm = new NotifyForm("Error sending batch");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
JObject jObject = JObject.Parse(responce);
if (jObject["error"].ToString() != "")
{
AddLog("Error: ");
AddLog(jObject["error"].ToString());
if (jObject["error"].ToString().Contains("Batch output addresses would exceed lookahead"))
{
NotifyForm notifyForm = new NotifyForm("Error: \nBatch output addresses would exceed lookahead\nYour batch might have too many TXs.");
notifyForm.ShowDialog();
notifyForm.Dispose();
}
else if (jObject["error"].ToString().Contains("Name is not registered"))
{
NotifyForm notifyForm = new NotifyForm("Error: \nName is not registered\nRemember you can't renew domains in transfer");
notifyForm.ShowDialog();
notifyForm.Dispose();
}
else
{
NotifyForm notifyForm = new NotifyForm("Error: \n" + jObject["error"].ToString());
notifyForm.ShowDialog();
notifyForm.Dispose();
}
return;
}
string[] domains = batches.Select(batch => batch.domain).ToArray();
string tx = await mainForm.ExportTransaction(jObject["result"].ToString(),domains);
if (tx != "Error")
{
ImportTXForm importTXForm = new ImportTXForm(mainForm, tx);
this.Hide();
importTXForm.ShowDialog();
importTXForm.Dispose();
this.Close();
}
}
else // watch only else // watch only
{ {
string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]"; string batchTX = "[" + string.Join(", ", batches.Select(batch => batch.ToString())) + "]";
@ -539,13 +592,7 @@ namespace FireWallet
return; return;
} }
StreamWriter sw = new StreamWriter(dir + "hsd-ledger/bin/names.txt"); string domainslist = string.Join(",", batches.Select(batch => "\\\"" + batch.domain + "\\\""));
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();
NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false); NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false);
notify.Show(); notify.Show();
@ -558,7 +605,9 @@ namespace FireWallet
proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "node.exe"; proc.StartInfo.FileName = "node.exe";
proc.StartInfo.WorkingDirectory = dir + "hsd-ledger/bin/"; 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(); var outputBuilder = new StringBuilder();
// Event handler for capturing output data // Event handler for capturing output data
@ -582,7 +631,7 @@ namespace FireWallet
if (output.Contains("Submitted TXID")) if (output.Contains("Submitted TXID"))
{ {
string hash = output.Substring(output.IndexOf("Submitted TXID") + 16, 64); 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", NotifyForm notifySuccess = new NotifyForm("Transaction Sent\nThis transaction could take up to 20 minutes to mine",
"Explorer", link); "Explorer", link);
notifySuccess.ShowDialog(); notifySuccess.ShowDialog();
@ -590,6 +639,8 @@ namespace FireWallet
} }
else else
{ {
AddLog(args);
AddLog(proc.StandardError.ReadToEnd());
NotifyForm notifyError = new NotifyForm("Error Transaction Failed\nCheck logs for more details"); NotifyForm notifyError = new NotifyForm("Error Transaction Failed\nCheck logs for more details");
notifyError.ShowDialog(); notifyError.ShowDialog();
notifyError.Dispose(); notifyError.Dispose();
@ -622,7 +673,7 @@ namespace FireWallet
} }
else if (b.method == "UPDATE") else if (b.method == "UPDATE")
{ {
sw.WriteLine(b.domain + "," + b.method + ",[" + string.Join(", ", b.update.Select(record => record.ToString())) + "]"); sw.WriteLine(b.domain + "," + b.method + ",[" + string.Join(";", b.update.Select(record => record.ToString())) + "]");
} }
else else
{ {
@ -640,17 +691,85 @@ namespace FireWallet
openFileDialog.Title = "Open Batch"; openFileDialog.Title = "Open Batch";
if (openFileDialog.ShowDialog() == DialogResult.OK) if (openFileDialog.ShowDialog() == DialogResult.OK)
{ {
StreamReader sr = new StreamReader(openFileDialog.FileName); try
string line;
string[] domains = new string[0];
while ((line = sr.ReadLine()) != null)
{ {
string[] split = line.Split(','); StreamReader sr = new StreamReader(openFileDialog.FileName);
try 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")
{
// Join the rest of the line
string[] updateArray = new string[split.Length - 2];
for (int i = 0; i < updateArray.Length; i++)
{
updateArray[i] = split[i + 2];
}
string updateString = string.Join(",", updateArray);
updateString.TrimStart('[');
updateString.TrimEnd(']');
string[] updateSplit = updateString.Split(';');
DNS[] UpdateRecords = new DNS[updateSplit.Length];
int r = 0;
foreach (string update in updateSplit)
{
string[] updateRecord = update.Split(',');
string type = updateRecord[0];
type = type.Split(':')[1].Replace("\"","").Trim();
switch (type)
{
case "NS":
string ns = updateRecord[1].Split(':')[1].Replace("\"","").Replace("}","").Trim();
UpdateRecords[r] = new DNS(type, ns);
break;
case "DS":
int keyTag = int.Parse(updateRecord[1].Split(':')[1]);
int algorithm = int.Parse(updateRecord[2].Split(':')[1]);
int digestType = int.Parse(updateRecord[3].Split(':')[1]);
string digest = updateRecord[4].Split(':')[1].Replace("\"", "").Replace("}", "");
UpdateRecords[r] = new DNS(type, keyTag, algorithm, digestType, digest);
break;
case "TXT":
string txt = updateRecord[1].Split(':')[1].Replace("\"", "").Replace("}", "");
txt = txt.Replace("[", "");
txt = txt.Replace("]", "");
UpdateRecords[r] = new DNS(type, new string[] { txt.Trim() });
break;
case "GLUE4":
case "GLUE6":
string nsGlue = updateRecord[1].Split(':')[1].Replace("\"", "").Trim();
string address = updateRecord[2].Split(':')[1].Replace("\"", "").Replace("}", "").Trim();
UpdateRecords[r] = new DNS(type, nsGlue, address);
break;
}
r++;
}
AddBatch(split[0], split[1], UpdateRecords);
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 // Select operation and import domains
string[] newDomains = new string[domains.Length + 1]; string[] newDomains = new string[domains.Length + 1];
@ -658,68 +777,53 @@ namespace FireWallet
{ {
newDomains[i] = domains[i]; newDomains[i] = domains[i];
} }
newDomains[domains.Length] = split[0]; newDomains[domains.Length] = line.Trim();
domains = newDomains; domains = newDomains;
continue;
} }
} }
catch (Exception ex)
if (split.Length == 2)
{ {
AddBatch(split[0], split[1]); AddLog("Error importing batch: " + ex.Message);
} NotifyForm notifyForm = new NotifyForm("Error importing batch");
else if (split.Length == 3) notifyForm.ShowDialog();
{ notifyForm.Dispose();
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;
} }
} }
catch (Exception ex) if (domains.Length > 0)
{ {
AddLog("Error importing batch: " + ex.Message); BatchImportForm batchImportForm = new BatchImportForm(domains,mainForm);
NotifyForm notifyForm = new NotifyForm("Error importing batch"); batchImportForm.ShowDialog();
notifyForm.ShowDialog(); if (batchImportForm.batches != null)
notifyForm.Dispose(); {
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 if (b.method == "UPDATE")
{
AddBatch(b.domain, b.method, b.update);
}
else
{
AddBatch(b.domain, b.method);
}
}
}
} }
} sr.Dispose();
if (domains.Length > 0) } catch (Exception ex)
{ {
BatchImportForm batchImportForm = new BatchImportForm(domains); AddLog("Error importing batch: " + ex.Message);
batchImportForm.ShowDialog(); NotifyForm notifyForm = new NotifyForm("Error importing batch\nMake sure the file is in not in use");
if (batchImportForm.batches != null) notifyForm.ShowDialog();
{ notifyForm.Dispose();
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);
}
}
}
} }
sr.Dispose();
} }
} }
@ -732,10 +836,10 @@ namespace FireWallet
/// <returns></returns> /// <returns></returns>
private async Task<string> APIPost(string path, bool wallet, string content) private async Task<string> APIPost(string path, bool wallet, string content)
{ {
string key = mainForm.nodeSettings["Key"]; string key = mainForm.NodeSettings["Key"];
string ip = mainForm.nodeSettings["IP"]; string ip = mainForm.NodeSettings["IP"];
string port = "1203"; string port = "1203";
if (mainForm.network == 1) if (mainForm.HSDNetwork == 1)
{ {
port = "1303"; port = "1303";
} }
@ -747,21 +851,26 @@ namespace FireWallet
req.Content = new StringContent(content); req.Content = new StringContent(content);
// Send request // Send request
HttpResponseMessage resp = await httpClient.SendAsync(req);
try try
{ {
resp.EnsureSuccessStatusCode(); HttpResponseMessage resp = await httpClient.SendAsync(req);
if (resp.StatusCode != HttpStatusCode.OK)
{
AddLog("Post Error: " + resp.StatusCode.ToString());
AddLog(await resp.Content.ReadAsStringAsync());
AddLog(content);
return "Error";
}
return await resp.Content.ReadAsStringAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
AddLog("Post Error: " + ex.Message); AddLog("Post Error: " + ex.Message);
AddLog(await resp.Content.ReadAsStringAsync());
AddLog(content);
return "Error"; return "Error";
} }
return await resp.Content.ReadAsStringAsync();
} }
} }
public class Batch public class Batch
@ -823,6 +932,10 @@ namespace FireWallet
return "[\"UPDATE\", \"" + domain + "\", " + records + "]"; return "[\"UPDATE\", \"" + domain + "\", " + records + "]";
} }
else if (method == "UPDATE")
{
return "[\"UPDATE\", \"" + domain + "\", {\"records\":[]}]";
}
return "[\"" + method + "\", \"" + domain + "\"]"; return "[\"" + method + "\", \"" + domain + "\"]";
} }
} }

View File

@ -72,7 +72,7 @@
comboBoxMode.FlatStyle = FlatStyle.Flat; comboBoxMode.FlatStyle = FlatStyle.Flat;
comboBoxMode.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); comboBoxMode.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
comboBoxMode.FormattingEnabled = true; comboBoxMode.FormattingEnabled = true;
comboBoxMode.Items.AddRange(new object[] { "OPEN", "BID", "REVEAL", "REDEEM", "RENEW", "TRANSFER", "FINALIZE", "CANCEL" }); comboBoxMode.Items.AddRange(new object[] { "OPEN", "BID", "REVEAL", "REDEEM", "REGISTER", "RENEW", "TRANSFER", "FINALIZE", "CANCEL" });
comboBoxMode.Location = new Point(346, 42); comboBoxMode.Location = new Point(346, 42);
comboBoxMode.Name = "comboBoxMode"; comboBoxMode.Name = "comboBoxMode";
comboBoxMode.Size = new Size(226, 29); comboBoxMode.Size = new Size(226, 29);

View File

@ -8,12 +8,14 @@ namespace FireWallet
Dictionary<string, string> theme; Dictionary<string, string> theme;
string[] domains; string[] domains;
public Batch[] batches { get; set; } public Batch[] batches { get; set; }
MainForm mainForm;
public BatchImportForm(string[] domains) public BatchImportForm(string[] domains, MainForm mainForm)
{ {
InitializeComponent(); InitializeComponent();
this.domains = domains; this.domains = domains;
comboBoxMode.SelectedIndex = 1; comboBoxMode.SelectedIndex = 1;
this.mainForm = mainForm;
} }
private void BatchImportForm_Load(object sender, EventArgs e) private void BatchImportForm_Load(object sender, EventArgs e)
@ -218,7 +220,7 @@ namespace FireWallet
this.Close(); this.Close();
} }
private void buttonImport_Click(object sender, EventArgs e) private async void buttonImport_Click(object sender, EventArgs e)
{ {
if (comboBoxMode.Text == "BID") if (comboBoxMode.Text == "BID")
{ {
@ -263,7 +265,7 @@ namespace FireWallet
} }
this.Close(); this.Close();
} }
else if (comboBoxMode.Text == "TRANSFER") else if (comboBoxMode.Text == "REGISTER")
{ {
batches = new Batch[0]; batches = new Batch[0];
foreach (string domain in listBoxDomains.Items) foreach (string domain in listBoxDomains.Items)
@ -272,7 +274,48 @@ namespace FireWallet
{ {
Batch[] newBatch = new Batch[batches.Length + 1]; Batch[] newBatch = new Batch[batches.Length + 1];
Array.Copy(batches, newBatch, batches.Length); Array.Copy(batches, newBatch, batches.Length);
newBatch[newBatch.Length - 1] = new Batch(domain, comboBoxMode.Text, textBoxToAddress.Text); newBatch[newBatch.Length - 1] = new Batch(domain,"UPDATE",new DNS[0]);
batches = newBatch;
}
}
this.Close();
}
else if (comboBoxMode.Text == "TRANSFER")
{
if (textBoxToAddress.Text == "")
{
MessageBox.Show("Please enter a to address");
return;
}
string address = textBoxToAddress.Text;
if (address.Substring(0,1) == "@")
{
address = await mainForm.HIP02Lookup(address.Substring(1));
if (address == "ERROR")
{
NotifyForm notify = new NotifyForm("Invalid HIP-02 address");
notify.ShowDialog();
notify.Dispose();
return;
}
}
if (!(await mainForm.ValidAddress(address)))
{
NotifyForm notify = new NotifyForm("Invalid address");
notify.ShowDialog();
notify.Dispose();
return;
}
batches = new Batch[0];
foreach (string domain in listBoxDomains.Items)
{
if (domain != "")
{
Batch[] newBatch = new Batch[batches.Length + 1];
Array.Copy(batches, newBatch, batches.Length);
newBatch[newBatch.Length - 1] = new Batch(domain, comboBoxMode.Text, address);
batches = newBatch; batches = newBatch;
} }
} }

View File

@ -27,7 +27,7 @@ namespace FireWallet
InitializeComponent(); InitializeComponent();
this.domain = domain; this.domain = domain;
this.mainForm = mainForm; this.mainForm = mainForm;
nodeSettings = mainForm.nodeSettings; nodeSettings = mainForm.NodeSettings;
cancel = true; cancel = true;
this.Text = domain + "/ DNS | FireWallet"; this.Text = domain + "/ DNS | FireWallet";
@ -363,6 +363,12 @@ namespace FireWallet
string contentDNS = "{\"method\": \"getnameresource\", \"params\": [\"" + domain + "\"]}"; string contentDNS = "{\"method\": \"getnameresource\", \"params\": [\"" + domain + "\"]}";
string responseDNS = await APIPost("", false, contentDNS); string responseDNS = await APIPost("", false, contentDNS);
JObject jObjectDNS = JObject.Parse(responseDNS); JObject jObjectDNS = JObject.Parse(responseDNS);
if (jObjectDNS["result"].ToString() == "")
{
return;
}
JObject result = (JObject)jObjectDNS["result"]; JObject result = (JObject)jObjectDNS["result"];
JArray records = (JArray)result["records"]; JArray records = (JArray)result["records"];
// For each record // For each record
@ -439,7 +445,7 @@ namespace FireWallet
string key = nodeSettings["Key"]; string key = nodeSettings["Key"];
string ip = nodeSettings["IP"]; string ip = nodeSettings["IP"];
string port = "1203"; string port = "1203";
if (mainForm.network == 1) if (mainForm.HSDNetwork == 1)
{ {
port = "1303"; port = "1303";
} }
@ -478,7 +484,7 @@ namespace FireWallet
string ip = nodeSettings["IP"]; string ip = nodeSettings["IP"];
string port = "1203"; string port = "1203";
if (mainForm.network == 1) if (mainForm.HSDNetwork == 1)
{ {
port = "1303"; port = "1303";
} }

View File

@ -32,36 +32,7 @@ namespace FireWallet
this.explorerTX = explorerTX; this.explorerTX = explorerTX;
this.explorerName = explorerName; this.explorerName = explorerName;
this.mainForm = mainForm; this.mainForm = mainForm;
} this.theme = mainForm.Theme;
#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;
}
// Apply theme // Apply theme
this.BackColor = ColorTranslator.FromHtml(theme["background"]); this.BackColor = ColorTranslator.FromHtml(theme["background"]);
@ -73,35 +44,12 @@ namespace FireWallet
// Need to specify this for each groupbox to override the black text // Need to specify this for each groupbox to override the black text
foreach (Control c in Controls) foreach (Control c in Controls)
{ {
ThemeControl(c); mainForm.ThemeControl(c);
} }
applyTransparency(mainForm.Theme);
// Transparancy
applyTransparency(theme);
} }
private void ThemeControl(Control c) #region Theme
{
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"]);
}
}
private void applyTransparency(Dictionary<string, string> theme) private void applyTransparency(Dictionary<string, string> theme)
{ {
if (theme.ContainsKey("transparent-mode")) 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 // Required for mica effect
internal enum AccentState internal enum AccentState
{ {
@ -209,7 +137,6 @@ namespace FireWallet
private void DomainForm_Load(object sender, EventArgs e) private void DomainForm_Load(object sender, EventArgs e)
{ {
UpdateTheme();
own = false; own = false;
StreamReader sr = new StreamReader(dir + "node.txt"); StreamReader sr = new StreamReader(dir + "node.txt");
nodeSettings = new Dictionary<string, string>(); nodeSettings = new Dictionary<string, string>();
@ -230,9 +157,9 @@ namespace FireWallet
network = Convert.ToInt32(nodeSettings["Network"]); network = Convert.ToInt32(nodeSettings["Network"]);
GetName(); GetName();
if (mainForm.watchOnly) if (mainForm.WatchOnly || mainForm.multiSig)
{ {
buttonActionMain.Enabled = false; // Only allow sending in batches for ledger buttonActionMain.Enabled = false; // Only allow sending in batches for ledger and multisig to prevent confusion
} }
} }
#region API #region API
@ -330,6 +257,14 @@ namespace FireWallet
{ {
labelStatusMain.Text = "Error"; labelStatusMain.Text = "Error";
} }
if (labelStatusReserved.Text == "True")
{
buttonActionAlt.Hide();
buttonActionMain.Hide();
groupBoxAction.Text = "Reserved";
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -344,6 +279,14 @@ namespace FireWallet
string contentDNS = "{\"method\": \"getnameresource\", \"params\": [\"" + domain + "\"]}"; string contentDNS = "{\"method\": \"getnameresource\", \"params\": [\"" + domain + "\"]}";
string responseDNS = await APIPost("", false, contentDNS); string responseDNS = await APIPost("", false, contentDNS);
JObject jObjectDNS = JObject.Parse(responseDNS); JObject jObjectDNS = JObject.Parse(responseDNS);
if (jObjectDNS["result"].ToString() == "")
{
// Not registered
groupBoxDNS.Visible = false;
return;
}
JObject result = (JObject)jObjectDNS["result"]; JObject result = (JObject)jObjectDNS["result"];
JArray records = (JArray)result["records"]; JArray records = (JArray)result["records"];
// For each record // For each record
@ -879,7 +822,14 @@ namespace FireWallet
if (!DNSEdit.cancel) if (!DNSEdit.cancel)
{ {
string records = string.Join(", ", DNSEdit.DNSrecords.Select(record => record.ToString())); string records = "";
if (DNSEdit.DNSrecords != null)
{
if (DNSEdit.DNSrecords.Count() > 0)
{
records = string.Join(", ", DNSEdit.DNSrecords.Select(record => record.ToString()));
}
}
string content = "{\"method\": \"sendupdate\", \"params\": [\"" + domain + "\", {\"records\": [" + records + "]}]}"; string content = "{\"method\": \"sendupdate\", \"params\": [\"" + domain + "\", {\"records\": [" + records + "]}]}";
string response = await APIPost("", true, content); string response = await APIPost("", true, content);

BIN
FireWallet/FW.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -6,17 +6,17 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>FW2.ico</ApplicationIcon> <ApplicationIcon>FW.ico</ApplicationIcon>
<Title>FireWallet</Title> <Title>FireWallet</Title>
<PackageProjectUrl>https://l.woodburn.au</PackageProjectUrl> <PackageProjectUrl>https://l.woodburn.au</PackageProjectUrl>
<PackageIcon>HSDBatcher.png</PackageIcon> <PackageIcon>HSDBatcher.png</PackageIcon>
<RepositoryUrl>https://github.com/Nathanwoodburn/FireWallet</RepositoryUrl> <RepositoryUrl>https://github.com/Nathanwoodburn/FireWallet</RepositoryUrl>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<Version>2.5</Version> <Version>4.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Content Include="FW2.ico" /> <Content Include="FW.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -27,7 +27,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DnsClient" Version="1.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
<PackageReference Include="QRCoder" Version="1.4.3" /> <PackageReference Include="QRCoder" Version="1.4.3" />
</ItemGroup> </ItemGroup>

223
FireWallet/ImportTXForm.Designer.cs generated Normal file
View File

@ -0,0 +1,223 @@
namespace FireWallet
{
partial class ImportTXForm
{
/// <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(ImportTXForm));
groupBoxIn = new GroupBox();
panelIn = new Panel();
groupBoxOut = new GroupBox();
panelOut = new Panel();
buttonSign = new Button();
Cancelbutton2 = new Button();
label1 = new Label();
labelSigsTotal = new Label();
labelSigsReq = new Label();
labelSigsSigned = new Label();
labelSigInfo = new Label();
buttonExport = new Button();
buttonSend = new Button();
groupBoxIn.SuspendLayout();
groupBoxOut.SuspendLayout();
SuspendLayout();
//
// groupBoxIn
//
groupBoxIn.Controls.Add(panelIn);
groupBoxIn.Location = new Point(12, 83);
groupBoxIn.Name = "groupBoxIn";
groupBoxIn.Size = new Size(376, 355);
groupBoxIn.TabIndex = 3;
groupBoxIn.TabStop = false;
groupBoxIn.Text = "Inputs";
//
// panelIn
//
panelIn.AutoScroll = true;
panelIn.Dock = DockStyle.Fill;
panelIn.Location = new Point(3, 19);
panelIn.Name = "panelIn";
panelIn.Size = new Size(370, 333);
panelIn.TabIndex = 0;
//
// groupBoxOut
//
groupBoxOut.Controls.Add(panelOut);
groupBoxOut.Location = new Point(391, 80);
groupBoxOut.Name = "groupBoxOut";
groupBoxOut.Size = new Size(484, 355);
groupBoxOut.TabIndex = 0;
groupBoxOut.TabStop = false;
groupBoxOut.Text = "Outputs";
//
// panelOut
//
panelOut.AutoScroll = true;
panelOut.Dock = DockStyle.Fill;
panelOut.Location = new Point(3, 19);
panelOut.Name = "panelOut";
panelOut.Size = new Size(478, 333);
panelOut.TabIndex = 0;
//
// buttonSign
//
buttonSign.FlatStyle = FlatStyle.Flat;
buttonSign.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonSign.Location = new Point(700, 444);
buttonSign.Name = "buttonSign";
buttonSign.Size = new Size(83, 36);
buttonSign.TabIndex = 2;
buttonSign.Text = "Sign";
buttonSign.UseVisualStyleBackColor = true;
buttonSign.Click += buttonSign_Click;
//
// Cancelbutton2
//
Cancelbutton2.FlatStyle = FlatStyle.Flat;
Cancelbutton2.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
Cancelbutton2.Location = new Point(12, 441);
Cancelbutton2.Name = "Cancelbutton2";
Cancelbutton2.Size = new Size(83, 36);
Cancelbutton2.TabIndex = 2;
Cancelbutton2.Text = "Cancel";
Cancelbutton2.UseVisualStyleBackColor = true;
Cancelbutton2.Click += Cancel;
//
// label1
//
label1.AutoSize = true;
label1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
label1.Location = new Point(12, 9);
label1.Name = "label1";
label1.Size = new Size(87, 21);
label1.TabIndex = 4;
label1.Text = "Signatures:";
//
// labelSigsTotal
//
labelSigsTotal.BackColor = Color.Blue;
labelSigsTotal.Location = new Point(105, 7);
labelSigsTotal.Name = "labelSigsTotal";
labelSigsTotal.Size = new Size(250, 32);
labelSigsTotal.TabIndex = 5;
//
// labelSigsReq
//
labelSigsReq.BackColor = Color.FromArgb(255, 128, 0);
labelSigsReq.Location = new Point(105, 7);
labelSigsReq.Name = "labelSigsReq";
labelSigsReq.Size = new Size(191, 32);
labelSigsReq.TabIndex = 6;
//
// labelSigsSigned
//
labelSigsSigned.BackColor = Color.Lime;
labelSigsSigned.Location = new Point(105, 7);
labelSigsSigned.Name = "labelSigsSigned";
labelSigsSigned.Size = new Size(100, 32);
labelSigsSigned.TabIndex = 7;
//
// labelSigInfo
//
labelSigInfo.AutoSize = true;
labelSigInfo.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
labelSigInfo.Location = new Point(361, 7);
labelSigInfo.Name = "labelSigInfo";
labelSigInfo.Size = new Size(19, 21);
labelSigInfo.TabIndex = 8;
labelSigInfo.Text = "#";
//
// buttonExport
//
buttonExport.Enabled = false;
buttonExport.FlatStyle = FlatStyle.Flat;
buttonExport.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonExport.Location = new Point(611, 444);
buttonExport.Name = "buttonExport";
buttonExport.Size = new Size(83, 36);
buttonExport.TabIndex = 2;
buttonExport.Text = "Export";
buttonExport.UseVisualStyleBackColor = true;
buttonExport.Click += buttonExport_Click;
//
// buttonSend
//
buttonSend.FlatStyle = FlatStyle.Flat;
buttonSend.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonSend.Location = new Point(789, 444);
buttonSend.Name = "buttonSend";
buttonSend.Size = new Size(83, 36);
buttonSend.TabIndex = 2;
buttonSend.Text = "Send";
buttonSend.UseVisualStyleBackColor = true;
buttonSend.Click += buttonSend_Click;
//
// ImportTXForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(887, 485);
Controls.Add(labelSigInfo);
Controls.Add(labelSigsSigned);
Controls.Add(labelSigsReq);
Controls.Add(labelSigsTotal);
Controls.Add(label1);
Controls.Add(groupBoxOut);
Controls.Add(groupBoxIn);
Controls.Add(buttonSend);
Controls.Add(buttonExport);
Controls.Add(Cancelbutton2);
Controls.Add(buttonSign);
FormBorderStyle = FormBorderStyle.FixedSingle;
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
Name = "ImportTXForm";
Text = "Import TX";
Load += ImportTXForm_Load;
groupBoxIn.ResumeLayout(false);
groupBoxOut.ResumeLayout(false);
ResumeLayout(false);
PerformLayout();
}
#endregion
private GroupBox groupBoxIn;
private GroupBox groupBoxOut;
private Button buttonSign;
private Button Cancelbutton2;
private Panel panelIn;
private Panel panelOut;
private Label label1;
private Label labelSigsTotal;
private Label labelSigsReq;
private Label labelSigsSigned;
private Label labelSigInfo;
private Button buttonExport;
private Button buttonSend;
}
}

347
FireWallet/ImportTXForm.cs Normal file
View File

@ -0,0 +1,347 @@
using System.Windows.Forms.VisualStyles;
using Newtonsoft.Json.Linq;
namespace FireWallet
{
public partial class ImportTXForm : Form
{
MainForm mainForm;
JObject tx;
int totalSigs;
int reqSigs;
int sigs;
string signedTX;
string[] domains;
public ImportTXForm(MainForm mainForm)
{
InitializeComponent();
this.mainForm = mainForm;
tx = null;
}
public ImportTXForm(MainForm mainForm, string tx)
{
InitializeComponent();
this.mainForm = mainForm;
JObject txObj = JObject.Parse(tx);
this.tx = txObj;
}
private void ImportTXForm_Load(object sender, EventArgs e)
{
// Default variables
domains = new string[0];
signedTX = "";
totalSigs = 3;
reqSigs = 2;
sigs = 0;
// Theme
this.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]);
foreach (Control c in Controls)
{
mainForm.ThemeControl(c);
}
if (tx == null)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Transaction files (*.json)|*.json";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string tx = System.IO.File.ReadAllText(openFileDialog.FileName);
try
{
JObject txObj = JObject.Parse(tx);
this.tx = txObj;
}
catch
{
NotifyForm notifyForm = new NotifyForm("Invalid transaction file.");
notifyForm.ShowDialog();
notifyForm.Dispose();
this.Close();
}
}
}
ParseTX();
}
private void Cancel(object sender, EventArgs e)
{
this.Close();
}
private async void ParseTX()
{
if (tx == null) this.Close();
string hex = tx["tx"].ToString();
string content = "{\"method\":\"decoderawtransaction\",\"params\":[\"" + hex + "\"]}";
string response = await mainForm.APIPost("", false, content);
if (response == null)
{
NotifyForm notifyForm = new NotifyForm("Error decoding transaction");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
JObject json = JObject.Parse(response);
if (json["error"].ToString() != "")
{
NotifyForm notifyForm = new NotifyForm("Error decoding transaction");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
JObject metadata = (JObject)tx["metadata"];
JArray metaInputs = (JArray)metadata["inputs"];
JArray metaOutputs = (JArray)metadata["outputs"];
JArray inputs = (JArray)json["result"]["vin"];
JArray outputs = (JArray)json["result"]["vout"];
// Get multisig info
JObject firstIn = (JObject)inputs[0];
JArray witnesses = (JArray)firstIn["txinwitness"];
string scriptSig = witnesses[witnesses.Count - 1].ToString();
// decode script
string sigGetContent = "{\"method\":\"decodescript\",\"params\":[\"" + scriptSig + "\"]}";
string sigGetResponse = await mainForm.APIPost("", false, sigGetContent);
if (sigGetResponse == null)
{
NotifyForm notifyForm = new NotifyForm("Error decoding transaction");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
JObject sigGetJson = JObject.Parse(sigGetResponse);
if (sigGetJson["error"].ToString() != "")
{
NotifyForm notifyForm = new NotifyForm("Error decoding transaction");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
JObject sigGetResult = (JObject)sigGetJson["result"];
string[] asm = sigGetResult["asm"].ToString().Split(" ");
string totalSigsStr = asm[asm.Length - 2];
totalSigs = int.Parse(totalSigsStr.Replace("OP_", ""));
reqSigs = int.Parse(sigGetResult["reqSigs"].ToString());
sigs = -1;
for (int i = 0; i < witnesses.Count; i++)
{
string witness = witnesses[i].ToString();
if (witness != "")
{
sigs++;
}
}
// Set sig label sizes
labelSigsReq.Width = (labelSigsTotal.Width / totalSigs) * reqSigs;
labelSigsSigned.Width = (labelSigsTotal.Width / totalSigs) * sigs;
labelSigInfo.Text = "Signed: " + sigs + "\nReq: " + reqSigs + " of " + totalSigs;
if (sigs >= totalSigs)
{
buttonSign.Enabled = false;
buttonSign.Text = "Signed";
}
for (int i = 0; i < inputs.Count; i++)
{
JObject input = (JObject)inputs[i];
JObject metaInput = (JObject)metaInputs[i];
Panel PanelInput = new Panel();
PanelInput.Size = new Size(panelIn.Width - SystemInformation.VerticalScrollBarWidth - 10, 50);
PanelInput.Location = new Point(5, panelIn.Controls.Count * 50);
PanelInput.BorderStyle = BorderStyle.FixedSingle;
if (metaInput.ContainsKey("sighashType"))
{
Label sighashType = new Label();
sighashType.Text = "Sighash Type: " + metaInput["sighashType"].ToString();
sighashType.Location = new Point(5, 25);
sighashType.AutoSize = true;
PanelInput.Controls.Add(sighashType);
}
string txid = input["txid"].ToString();
int vout = int.Parse(input["vout"].ToString());
string txInfo = await mainForm.APIGet("tx/" + txid, false);
if (txInfo == "Error" || txInfo == "")
{
NotifyForm notifyForm = new NotifyForm("Error getting transaction info");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
else
{
JObject txInfoJson = JObject.Parse(txInfo);
JArray txoutputs = (JArray)txInfoJson["outputs"];
JObject txoutput = (JObject)txoutputs[vout];
string txoutputAddress = txoutput["address"].ToString();
Label address = new Label();
string addressString = txoutputAddress.Substring(0, 5) + "..." + txoutputAddress.Substring(txoutputAddress.Length - 5, 5);
address.Text = "Address: " + addressString;
address.Location = new Point(5, 5);
address.AutoSize = true;
PanelInput.Controls.Add(address);
Label amount = new Label();
Decimal value = Decimal.Parse(txoutput["value"].ToString()) / 1000000;
amount.Text = "Amount: " + value.ToString();
amount.Location = new Point(5, 25);
amount.AutoSize = true;
PanelInput.Controls.Add(amount);
}
panelIn.Controls.Add(PanelInput);
}
for (int i = 0; i < outputs.Count; i++)
{
JObject output = (JObject)outputs[i];
JObject metaOutput = (JObject)metaOutputs[i];
Panel PanelOutput = new Panel();
PanelOutput.Size = new Size(panelOut.Width - SystemInformation.VerticalScrollBarWidth - 10, 50);
PanelOutput.Location = new Point(5, panelOut.Controls.Count * 50);
PanelOutput.BorderStyle = BorderStyle.FixedSingle;
Label address = new Label();
JObject addressRaw = (JObject)output["address"];
string addressString = addressRaw["string"].ToString().Substring(0, 5) + "..." + addressRaw["string"].ToString().Substring(addressRaw["string"].ToString().Length - 5, 5);
address.Text = "Address: " + addressString;
address.Location = new Point(5, 5);
address.AutoSize = true;
PanelOutput.Controls.Add(address);
JObject covenant = (JObject)output["covenant"];
if (covenant.ContainsKey("action"))
{
if (covenant["action"].ToString() != "NONE")
{
if (metaOutput.ContainsKey("name"))
{
Label covenantLabel = new Label();
string name = metaOutput["name"].ToString();
covenantLabel.Text = covenant["action"].ToString() + ": " + name;
covenantLabel.Location = new Point(5, 25);
covenantLabel.AutoSize = true;
PanelOutput.Controls.Add(covenantLabel);
string[] domainsNew = new string[domains.Length + 1];
for (int j = 0; j < domains.Length; j++)
{
domainsNew[j] = domains[j];
}
domainsNew[domainsNew.Length - 1] = name;
domains = domainsNew;
}
}
}
bool own = false;
string addressResp = await mainForm.APIGet("wallet/" + mainForm.Account + "/key/" + addressRaw["string"].ToString(), true);
if (addressResp != "Error") own = true;
if (own)
{
Label ownAddress = new Label();
ownAddress.Text = "Own Address";
ownAddress.Location = new Point(PanelOutput.Width - 150, 5);
ownAddress.AutoSize = true;
PanelOutput.Controls.Add(ownAddress);
}
Label amount = new Label();
Decimal value = Decimal.Parse(output["value"].ToString());
amount.Text = "Amount: " + value.ToString();
amount.Location = new Point(PanelOutput.Width - 150, 25);
amount.AutoSize = true;
PanelOutput.Controls.Add(amount);
panelOut.Controls.Add(PanelOutput);
}
}
private async void buttonSign_Click(object sender, EventArgs e)
{
if (!mainForm.WatchOnly)
{
string content = "{\"tx\":\"" + tx["tx"].ToString() + "\", \"passphrase\":\"" + mainForm.Password + "\"}";
string response = await mainForm.APIPost("wallet/" + mainForm.Account + "/sign", true, content);
if (response == "Error" || response == "")
{
NotifyForm notifyForm = new NotifyForm("Error signing transaction");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
buttonSign.Enabled = false;
buttonExport.Enabled = true;
sigs++;
// Set sig label sizes
labelSigsReq.Width = (labelSigsTotal.Width / totalSigs) * reqSigs;
labelSigsSigned.Width = (labelSigsTotal.Width / totalSigs) * sigs;
labelSigInfo.Text = "Signed: " + sigs + "\nReq: " + reqSigs + " of " + totalSigs;
signedTX = response;
} else {
NotifyForm notifyForm = new NotifyForm("Ledger signing not supported yet 😢");
notifyForm.ShowDialog();
notifyForm.Dispose();
}
}
private void buttonExport_Click(object sender, EventArgs e)
{
mainForm.ExportTransaction(signedTX,domains);
}
private async void buttonSend_Click(object sender, EventArgs e)
{
string content = "";
if (signedTX != "")
{
JObject signed = JObject.Parse(signedTX);
content = "{\"method\":\"sendrawtransaction\", \"params\":[\"" + signed["hex"].ToString() + "\"]}";
}
else
{
content = "{\"method\":\"sendrawtransaction\", \"params\":[\"" + tx["tx"].ToString() + "\"]}";
}
string response = await mainForm.APIPost("", false, content);
if (response == "Error" || response == "")
{
mainForm.AddLog(response);
NotifyForm notifyError = new NotifyForm("Error sending transaction");
notifyError.ShowDialog();
notifyError.Dispose();
return;
}
JObject responseJson = JObject.Parse(response);
if (responseJson["error"].ToString() != "")
{
mainForm.AddLog(response);
JObject error = (JObject)responseJson["error"];
NotifyForm notifyError = new NotifyForm("Error sending transaction\n" + error["message"].ToString());
notifyError.ShowDialog();
notifyError.Dispose();
return;
}
string txHash = responseJson["result"].ToString();
NotifyForm notifyForm = new NotifyForm("Transaction sent\nIf the transaction hasn't been signed it might not be mined", "Explorer", mainForm.UserSettings["explorer-tx"] + txHash);
notifyForm.ShowDialog();
notifyForm.Dispose();
this.Close();
}
}
}

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

@ -39,8 +39,15 @@ namespace FireWallet
toolStripStatusLabelNetwork = new ToolStripStatusLabel(); toolStripStatusLabelNetwork = new ToolStripStatusLabel();
toolStripStatusLabelstatus = new ToolStripStatusLabel(); toolStripStatusLabelstatus = new ToolStripStatusLabel();
toolStripStatusLabelaccount = new ToolStripStatusLabel(); toolStripStatusLabelaccount = new ToolStripStatusLabel();
toolStripStatusLabelMultisig = new ToolStripStatusLabel();
toolStripStatusLabelLedger = new ToolStripStatusLabel(); toolStripStatusLabelLedger = new ToolStripStatusLabel();
toolStripSplitButtonlogout = new ToolStripSplitButton(); toolStripSplitButtonlogout = new ToolStripSplitButton();
toolStripDropDownButtonHelp = new ToolStripDropDownButton();
githubToolStripMenuItem = new ToolStripMenuItem();
websiteToolStripMenuItem = new ToolStripMenuItem();
supportDiscordServerToolStripMenuItem = new ToolStripMenuItem();
toolStripSeparator1 = new ToolStripSeparator();
otherProjectsToolStripMenuItem = new ToolStripMenuItem();
timerNodeStatus = new System.Windows.Forms.Timer(components); timerNodeStatus = new System.Windows.Forms.Timer(components);
panelaccount = new Panel(); panelaccount = new Panel();
groupBoxaccount = new GroupBox(); groupBoxaccount = new GroupBox();
@ -53,13 +60,15 @@ namespace FireWallet
buttonaccountnew = new Button(); buttonaccountnew = new Button();
panelNav = new Panel(); panelNav = new Panel();
buttonNavSettings = new Button(); buttonNavSettings = new Button();
buttonMultiSign = new Button();
buttonBatch = new Button(); buttonBatch = new Button();
buttonNavDomains = new Button(); buttonNavDomains = new Button();
buttonNavReceive = new Button(); buttonNavReceive = new Button();
buttonNavSend = new Button(); buttonNavSend = new Button();
buttonNavPortfolio = new Button(); buttonNavPortfolio = new Button();
panelPortfolio = new Panel(); panelPortfolio = new Panel();
buttonRenewAll = new Button(); buttonSendAll = new Button();
buttonRedeemAll = new Button();
buttonRevealAll = new Button(); buttonRevealAll = new Button();
groupBoxTransactions = new GroupBox(); groupBoxTransactions = new GroupBox();
groupBoxinfo = new GroupBox(); groupBoxinfo = new GroupBox();
@ -70,7 +79,9 @@ namespace FireWallet
labelBalanceTotal = new Label(); labelBalanceTotal = new Label();
labelLocked = new Label(); labelLocked = new Label();
labelBalance = new Label(); labelBalance = new Label();
buttonRenewAll = new Button();
panelSend = new Panel(); panelSend = new Panel();
labelSendingHIPAddress = new Label();
checkBoxSendSubFee = new CheckBox(); checkBoxSendSubFee = new CheckBox();
buttonSendMax = new Button(); buttonSendMax = new Button();
buttonSendHNS = new Button(); buttonSendHNS = new Button();
@ -82,6 +93,7 @@ namespace FireWallet
labelSendingAmount = new Label(); labelSendingAmount = new Label();
labelSendingTo = new Label(); labelSendingTo = new Label();
labelSendPrompt = new Label(); labelSendPrompt = new Label();
labelHIPArrow = new Label();
panelRecieve = new Panel(); panelRecieve = new Panel();
buttonAddressVerify = new Button(); buttonAddressVerify = new Button();
pictureBoxReceiveQR = new PictureBox(); pictureBoxReceiveQR = new PictureBox();
@ -89,6 +101,8 @@ namespace FireWallet
textBoxReceiveAddress = new TextBox(); textBoxReceiveAddress = new TextBox();
labelReceive1 = new Label(); labelReceive1 = new Label();
panelDomains = new Panel(); panelDomains = new Panel();
labelDomainSort = new Label();
comboBoxDomainSort = new ComboBox();
buttonExportDomains = new Button(); buttonExportDomains = new Button();
groupBoxDomains = new GroupBox(); groupBoxDomains = new GroupBox();
panelDomainList = new Panel(); panelDomainList = new Panel();
@ -116,6 +130,7 @@ namespace FireWallet
textBoxExAddr = new TextBox(); textBoxExAddr = new TextBox();
labelSettings4 = new Label(); labelSettings4 = new Label();
textBoxExTX = new TextBox(); textBoxExTX = new TextBox();
buttonMultiSettings = new Button();
statusStripmain.SuspendLayout(); statusStripmain.SuspendLayout();
panelaccount.SuspendLayout(); panelaccount.SuspendLayout();
groupBoxaccount.SuspendLayout(); groupBoxaccount.SuspendLayout();
@ -139,7 +154,7 @@ namespace FireWallet
// statusStripmain // statusStripmain
// //
statusStripmain.Dock = DockStyle.Top; statusStripmain.Dock = DockStyle.Top;
statusStripmain.Items.AddRange(new ToolStripItem[] { toolStripStatusLabelNetwork, toolStripStatusLabelstatus, toolStripStatusLabelaccount, toolStripStatusLabelLedger, toolStripSplitButtonlogout }); statusStripmain.Items.AddRange(new ToolStripItem[] { toolStripStatusLabelNetwork, toolStripStatusLabelstatus, toolStripStatusLabelaccount, toolStripStatusLabelMultisig, toolStripStatusLabelLedger, toolStripSplitButtonlogout, toolStripDropDownButtonHelp });
statusStripmain.Location = new Point(0, 0); statusStripmain.Location = new Point(0, 0);
statusStripmain.Name = "statusStripmain"; statusStripmain.Name = "statusStripmain";
statusStripmain.Size = new Size(1152, 22); statusStripmain.Size = new Size(1152, 22);
@ -171,12 +186,20 @@ namespace FireWallet
toolStripStatusLabelaccount.Size = new Size(55, 17); toolStripStatusLabelaccount.Size = new Size(55, 17);
toolStripStatusLabelaccount.Text = "Account:"; toolStripStatusLabelaccount.Text = "Account:";
// //
// toolStripStatusLabelMultisig
//
toolStripStatusLabelMultisig.Margin = new Padding(50, 3, 50, 2);
toolStripStatusLabelMultisig.Name = "toolStripStatusLabelMultisig";
toolStripStatusLabelMultisig.Size = new Size(50, 17);
toolStripStatusLabelMultisig.Text = "Multisig";
toolStripStatusLabelMultisig.Visible = false;
//
// toolStripStatusLabelLedger // toolStripStatusLabelLedger
// //
toolStripStatusLabelLedger.Margin = new Padding(50, 3, 50, 2); toolStripStatusLabelLedger.Margin = new Padding(50, 3, 50, 2);
toolStripStatusLabelLedger.Name = "toolStripStatusLabelLedger"; toolStripStatusLabelLedger.Name = "toolStripStatusLabelLedger";
toolStripStatusLabelLedger.Size = new Size(71, 17); toolStripStatusLabelLedger.Size = new Size(68, 17);
toolStripStatusLabelLedger.Text = "Cold Wallet:"; toolStripStatusLabelLedger.Text = "Cold Wallet";
toolStripStatusLabelLedger.Visible = false; toolStripStatusLabelLedger.Visible = false;
// //
// toolStripSplitButtonlogout // toolStripSplitButtonlogout
@ -190,6 +213,51 @@ namespace FireWallet
toolStripSplitButtonlogout.Visible = false; toolStripSplitButtonlogout.Visible = false;
toolStripSplitButtonlogout.ButtonClick += Logout; 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;
//
// toolStripSeparator1
//
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;
//
// timerNodeStatus // timerNodeStatus
// //
timerNodeStatus.Enabled = true; timerNodeStatus.Enabled = true;
@ -299,6 +367,8 @@ namespace FireWallet
// panelNav // panelNav
// //
panelNav.Controls.Add(buttonNavSettings); panelNav.Controls.Add(buttonNavSettings);
panelNav.Controls.Add(buttonMultiSettings);
panelNav.Controls.Add(buttonMultiSign);
panelNav.Controls.Add(buttonBatch); panelNav.Controls.Add(buttonBatch);
panelNav.Controls.Add(buttonNavDomains); panelNav.Controls.Add(buttonNavDomains);
panelNav.Controls.Add(buttonNavReceive); panelNav.Controls.Add(buttonNavReceive);
@ -323,6 +393,19 @@ namespace FireWallet
buttonNavSettings.UseVisualStyleBackColor = true; buttonNavSettings.UseVisualStyleBackColor = true;
buttonNavSettings.Click += buttonNavSettings_Click; buttonNavSettings.Click += buttonNavSettings_Click;
// //
// buttonMultiSign
//
buttonMultiSign.FlatStyle = FlatStyle.Flat;
buttonMultiSign.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonMultiSign.Location = new Point(12, 301);
buttonMultiSign.Name = "buttonMultiSign";
buttonMultiSign.Size = new Size(89, 30);
buttonMultiSign.TabIndex = 3;
buttonMultiSign.TabStop = false;
buttonMultiSign.Text = "Import TX";
buttonMultiSign.UseVisualStyleBackColor = true;
buttonMultiSign.Click += buttonMultiSign_Click;
//
// buttonBatch // buttonBatch
// //
buttonBatch.FlatStyle = FlatStyle.Flat; buttonBatch.FlatStyle = FlatStyle.Flat;
@ -390,27 +473,41 @@ namespace FireWallet
// //
// panelPortfolio // panelPortfolio
// //
panelPortfolio.Controls.Add(buttonSendAll);
panelPortfolio.Controls.Add(buttonRedeemAll);
panelPortfolio.Controls.Add(buttonRevealAll); panelPortfolio.Controls.Add(buttonRevealAll);
panelPortfolio.Controls.Add(groupBoxTransactions); panelPortfolio.Controls.Add(groupBoxTransactions);
panelPortfolio.Controls.Add(groupBoxinfo); panelPortfolio.Controls.Add(groupBoxinfo);
panelPortfolio.Controls.Add(groupBoxbalance); panelPortfolio.Controls.Add(groupBoxbalance);
panelPortfolio.Location = new Point(1065, 80); panelPortfolio.Location = new Point(140, 35);
panelPortfolio.Name = "panelPortfolio"; panelPortfolio.Name = "panelPortfolio";
panelPortfolio.Size = new Size(956, 538); panelPortfolio.Size = new Size(956, 538);
panelPortfolio.TabIndex = 7; panelPortfolio.TabIndex = 7;
panelPortfolio.Visible = false; panelPortfolio.Visible = false;
// //
// buttonRenewAll // buttonSendAll
// //
buttonRenewAll.FlatStyle = FlatStyle.Flat; buttonSendAll.FlatStyle = FlatStyle.Flat;
buttonRenewAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); buttonSendAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonRenewAll.Location = new Point(813, 9); buttonSendAll.Location = new Point(761, 12);
buttonRenewAll.Name = "buttonRenewAll"; buttonSendAll.Name = "buttonSendAll";
buttonRenewAll.Size = new Size(89, 32); buttonSendAll.Size = new Size(106, 44);
buttonRenewAll.TabIndex = 10; buttonSendAll.TabIndex = 9;
buttonRenewAll.Text = "Renew All"; buttonSendAll.Text = "Send All TXs";
buttonRenewAll.UseVisualStyleBackColor = true; buttonSendAll.UseVisualStyleBackColor = true;
buttonRenewAll.Click += buttonRenewAll_Click; buttonSendAll.Click += buttonSendAll_Click;
//
// buttonRedeemAll
//
buttonRedeemAll.FlatStyle = FlatStyle.Flat;
buttonRedeemAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonRedeemAll.Location = new Point(649, 12);
buttonRedeemAll.Name = "buttonRedeemAll";
buttonRedeemAll.Size = new Size(106, 44);
buttonRedeemAll.TabIndex = 9;
buttonRedeemAll.Text = "Redeem All";
buttonRedeemAll.UseVisualStyleBackColor = true;
buttonRedeemAll.Click += buttonRedeemAll_Click;
// //
// buttonRevealAll // buttonRevealAll
// //
@ -418,7 +515,7 @@ namespace FireWallet
buttonRevealAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); buttonRevealAll.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonRevealAll.Location = new Point(537, 12); buttonRevealAll.Location = new Point(537, 12);
buttonRevealAll.Name = "buttonRevealAll"; buttonRevealAll.Name = "buttonRevealAll";
buttonRevealAll.Size = new Size(89, 44); buttonRevealAll.Size = new Size(106, 44);
buttonRevealAll.TabIndex = 9; buttonRevealAll.TabIndex = 9;
buttonRevealAll.Text = "Reveal All"; buttonRevealAll.Text = "Reveal All";
buttonRevealAll.UseVisualStyleBackColor = true; buttonRevealAll.UseVisualStyleBackColor = true;
@ -518,8 +615,21 @@ namespace FireWallet
labelBalance.TabIndex = 0; labelBalance.TabIndex = 0;
labelBalance.Text = "labelBalance"; 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
// //
panelSend.Controls.Add(labelSendingHIPAddress);
panelSend.Controls.Add(checkBoxSendSubFee); panelSend.Controls.Add(checkBoxSendSubFee);
panelSend.Controls.Add(buttonSendMax); panelSend.Controls.Add(buttonSendMax);
panelSend.Controls.Add(buttonSendHNS); panelSend.Controls.Add(buttonSendHNS);
@ -531,12 +641,23 @@ namespace FireWallet
panelSend.Controls.Add(labelSendingAmount); panelSend.Controls.Add(labelSendingAmount);
panelSend.Controls.Add(labelSendingTo); panelSend.Controls.Add(labelSendingTo);
panelSend.Controls.Add(labelSendPrompt); panelSend.Controls.Add(labelSendPrompt);
panelSend.Location = new Point(1113, 42); panelSend.Controls.Add(labelHIPArrow);
panelSend.Location = new Point(1041, 235);
panelSend.Name = "panelSend"; panelSend.Name = "panelSend";
panelSend.Size = new Size(974, 521); panelSend.Size = new Size(974, 521);
panelSend.TabIndex = 2; panelSend.TabIndex = 2;
panelSend.Visible = false; 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
// //
checkBoxSendSubFee.AutoSize = true; checkBoxSendSubFee.AutoSize = true;
@ -579,11 +700,11 @@ namespace FireWallet
// //
labelSendingError.AutoSize = true; labelSendingError.AutoSize = true;
labelSendingError.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); 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.Name = "labelSendingError";
labelSendingError.Size = new Size(52, 21); labelSendingError.Size = new Size(78, 21);
labelSendingError.TabIndex = 13; labelSendingError.TabIndex = 13;
labelSendingError.Text = "label1"; labelSendingError.Text = "labelError";
labelSendingError.Visible = false; labelSendingError.Visible = false;
// //
// labelSendingFee // labelSendingFee
@ -654,6 +775,17 @@ namespace FireWallet
labelSendPrompt.TabIndex = 0; labelSendPrompt.TabIndex = 0;
labelSendPrompt.Text = "Send HNS"; 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
// //
panelRecieve.Controls.Add(buttonAddressVerify); panelRecieve.Controls.Add(buttonAddressVerify);
@ -721,17 +853,42 @@ namespace FireWallet
// //
// panelDomains // panelDomains
// //
panelDomains.Controls.Add(labelDomainSort);
panelDomains.Controls.Add(comboBoxDomainSort);
panelDomains.Controls.Add(buttonRenewAll); panelDomains.Controls.Add(buttonRenewAll);
panelDomains.Controls.Add(buttonExportDomains); panelDomains.Controls.Add(buttonExportDomains);
panelDomains.Controls.Add(groupBoxDomains); panelDomains.Controls.Add(groupBoxDomains);
panelDomains.Controls.Add(labelDomainSearch); panelDomains.Controls.Add(labelDomainSearch);
panelDomains.Controls.Add(textBoxDomainSearch); panelDomains.Controls.Add(textBoxDomainSearch);
panelDomains.Location = new Point(120, 48); panelDomains.Location = new Point(1122, 35);
panelDomains.Name = "panelDomains"; panelDomains.Name = "panelDomains";
panelDomains.Size = new Size(920, 536); panelDomains.Size = new Size(920, 536);
panelDomains.TabIndex = 18; panelDomains.TabIndex = 18;
panelDomains.Visible = false; 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
// //
buttonExportDomains.FlatStyle = FlatStyle.Flat; buttonExportDomains.FlatStyle = FlatStyle.Flat;
@ -792,7 +949,7 @@ namespace FireWallet
panelSettings.Controls.Add(buttonSettingsSave); panelSettings.Controls.Add(buttonSettingsSave);
panelSettings.Controls.Add(groupBoxSettingsExplorer); panelSettings.Controls.Add(groupBoxSettingsExplorer);
panelSettings.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); panelSettings.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
panelSettings.Location = new Point(1065, 211); panelSettings.Location = new Point(1065, 51);
panelSettings.Name = "panelSettings"; panelSettings.Name = "panelSettings";
panelSettings.Size = new Size(930, 550); panelSettings.Size = new Size(930, 550);
panelSettings.TabIndex = 19; panelSettings.TabIndex = 19;
@ -1002,25 +1159,39 @@ namespace FireWallet
textBoxExTX.Size = new Size(307, 29); textBoxExTX.Size = new Size(307, 29);
textBoxExTX.TabIndex = 1; textBoxExTX.TabIndex = 1;
// //
// buttonMultiSettings
//
buttonMultiSettings.FlatStyle = FlatStyle.Flat;
buttonMultiSettings.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonMultiSettings.Location = new Point(12, 466);
buttonMultiSettings.Name = "buttonMultiSettings";
buttonMultiSettings.Size = new Size(89, 30);
buttonMultiSettings.TabIndex = 3;
buttonMultiSettings.TabStop = false;
buttonMultiSettings.Text = "Multisig";
buttonMultiSettings.UseVisualStyleBackColor = true;
buttonMultiSettings.Click += buttonMultiSettings_Click;
//
// MainForm // MainForm
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1152, 575); ClientSize = new Size(1152, 575);
Controls.Add(panelDomains);
Controls.Add(panelSend);
Controls.Add(panelSettings);
Controls.Add(panelaccount); Controls.Add(panelaccount);
Controls.Add(panelPortfolio); Controls.Add(panelPortfolio);
Controls.Add(panelRecieve); Controls.Add(panelRecieve);
Controls.Add(panelDomains);
Controls.Add(panelSend);
Controls.Add(panelNav); Controls.Add(panelNav);
Controls.Add(statusStripmain); Controls.Add(statusStripmain);
Controls.Add(panelSettings);
Icon = (Icon)resources.GetObject("$this.Icon"); Icon = (Icon)resources.GetObject("$this.Icon");
Name = "MainForm"; Name = "MainForm";
Opacity = 0D; Opacity = 0D;
Text = "FireWallet"; Text = "FireWallet";
FormClosing += MainForm_Closing; FormClosing += MainForm_Closing;
Load += MainForm_Load; Load += MainForm_Load;
ResizeEnd += MainForm_ResizeEnd;
Resize += Form1_Resize; Resize += Form1_Resize;
statusStripmain.ResumeLayout(false); statusStripmain.ResumeLayout(false);
statusStripmain.PerformLayout(); statusStripmain.PerformLayout();
@ -1137,5 +1308,20 @@ namespace FireWallet
private Button buttonRevealAll; private Button buttonRevealAll;
private Button buttonExportDomains; private Button buttonExportDomains;
private Button buttonRenewAll; 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;
private Button buttonRedeemAll;
private Button buttonSendAll;
private ToolStripStatusLabel toolStripStatusLabelMultisig;
private Button buttonMultiSign;
private Button buttonMultiSettings;
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,141 @@
namespace FireWallet
{
partial class MultisigSettingsForm
{
/// <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(MultisigSettingsForm));
groupBoxSigners = new GroupBox();
panelSigners = new Panel();
labelSigners = new Label();
groupBoxAddSig = new GroupBox();
buttoAddSigner = new Button();
textBoxAddSig = new TextBox();
labelAddXpub = new Label();
groupBoxSigners.SuspendLayout();
groupBoxAddSig.SuspendLayout();
SuspendLayout();
//
// groupBoxSigners
//
groupBoxSigners.Controls.Add(panelSigners);
groupBoxSigners.Location = new Point(0, 0);
groupBoxSigners.Name = "groupBoxSigners";
groupBoxSigners.Size = new Size(418, 463);
groupBoxSigners.TabIndex = 0;
groupBoxSigners.TabStop = false;
groupBoxSigners.Text = "Signers";
//
// panelSigners
//
panelSigners.Dock = DockStyle.Fill;
panelSigners.Location = new Point(3, 19);
panelSigners.Name = "panelSigners";
panelSigners.Size = new Size(412, 441);
panelSigners.TabIndex = 0;
//
// labelSigners
//
labelSigners.AutoSize = true;
labelSigners.Location = new Point(424, 9);
labelSigners.Name = "labelSigners";
labelSigners.Size = new Size(48, 15);
labelSigners.TabIndex = 1;
labelSigners.Text = "Signers:";
//
// groupBoxAddSig
//
groupBoxAddSig.Controls.Add(buttoAddSigner);
groupBoxAddSig.Controls.Add(textBoxAddSig);
groupBoxAddSig.Controls.Add(labelAddXpub);
groupBoxAddSig.Location = new Point(421, 255);
groupBoxAddSig.Name = "groupBoxAddSig";
groupBoxAddSig.Size = new Size(381, 208);
groupBoxAddSig.TabIndex = 2;
groupBoxAddSig.TabStop = false;
groupBoxAddSig.Text = "Add Signer";
//
// buttoAddSigner
//
buttoAddSigner.FlatStyle = FlatStyle.Flat;
buttoAddSigner.Location = new Point(6, 45);
buttoAddSigner.Name = "buttoAddSigner";
buttoAddSigner.Size = new Size(75, 23);
buttoAddSigner.TabIndex = 2;
buttoAddSigner.Text = "Add";
buttoAddSigner.UseVisualStyleBackColor = true;
buttoAddSigner.Click += buttoAddSigner_Click;
//
// textBoxAddSig
//
textBoxAddSig.Location = new Point(51, 16);
textBoxAddSig.Name = "textBoxAddSig";
textBoxAddSig.Size = new Size(324, 23);
textBoxAddSig.TabIndex = 1;
textBoxAddSig.KeyDown += textBoxAddSig_KeyDown;
//
// labelAddXpub
//
labelAddXpub.AutoSize = true;
labelAddXpub.Location = new Point(6, 19);
labelAddXpub.Name = "labelAddXpub";
labelAddXpub.Size = new Size(39, 15);
labelAddXpub.TabIndex = 0;
labelAddXpub.Text = "XPUB:";
//
// MultisigSettingsForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(814, 475);
Controls.Add(groupBoxAddSig);
Controls.Add(labelSigners);
Controls.Add(groupBoxSigners);
FormBorderStyle = FormBorderStyle.Fixed3D;
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
Name = "MultisigSettingsForm";
Text = "Multisig Settings";
Load += MultisigSettingsForm_Load;
groupBoxSigners.ResumeLayout(false);
groupBoxAddSig.ResumeLayout(false);
groupBoxAddSig.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private GroupBox groupBoxSigners;
private Label labelSigners;
private Panel panelSigners;
private GroupBox groupBoxAddSig;
private Button buttoAddSigner;
private TextBox textBoxAddSig;
private Label labelAddXpub;
}
}

View File

@ -0,0 +1,212 @@
using Newtonsoft.Json.Linq;
namespace FireWallet
{
public partial class MultisigSettingsForm : Form
{
MainForm mainForm;
int n;
int m;
int current;
string OwnKey;
public MultisigSettingsForm(MainForm mainForm)
{
InitializeComponent();
this.mainForm = mainForm;
this.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]);
foreach (Control c in Controls)
{
mainForm.ThemeControl(c);
}
}
private void MultisigSettingsForm_Load(object sender, EventArgs e)
{
UpdateInfo();
}
private async void UpdateInfo()
{
// Get multisig info
string infoResp = await mainForm.APIGet("wallet/" + mainForm.Account + "/account/default", true);
if (infoResp == "Error")
{
NotifyForm notifyForm = new NotifyForm("Error getting multisig info");
notifyForm.ShowDialog();
notifyForm.Dispose();
this.Close();
}
JObject info = JObject.Parse(infoResp);
n = int.Parse(info["n"].ToString());
m = int.Parse(info["m"].ToString());
labelSigners.Text = "Signers: " + m + "/" + n;
panelSigners.Controls.Clear();
Panel selfInfo = new Panel();
selfInfo.Width = panelSigners.Width - SystemInformation.VerticalScrollBarWidth;
selfInfo.Height = 50;
selfInfo.Location = new Point(0, 0);
selfInfo.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]);
selfInfo.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]);
selfInfo.BorderStyle = BorderStyle.FixedSingle;
Label selfLabel = new Label();
selfLabel.Text = "Own Key";
selfLabel.Location = new Point(10, 10);
selfLabel.AutoSize = true;
selfInfo.Controls.Add(selfLabel);
Label pubKey = new Label();
OwnKey = info["accountKey"].ToString();
string pukKeyShort = info["accountKey"].ToString().Substring(0, 10) + "..." + info["accountKey"].ToString().Substring(info["accountKey"].ToString().Length - 10);
pubKey.Text = pukKeyShort;
pubKey.Location = new Point(10, 30);
pubKey.AutoSize = true;
selfInfo.Controls.Add(pubKey);
Button copyPubKey = new Button();
copyPubKey.Text = "Copy";
copyPubKey.AutoSize = true;
copyPubKey.FlatStyle = FlatStyle.Flat;
copyPubKey.Location = new Point(selfInfo.Width - copyPubKey.Width - 10, 10);
copyPubKey.Click += (s, e) =>
{
Clipboard.SetText(OwnKey);
};
selfInfo.Controls.Add(copyPubKey);
panelSigners.Controls.Add(selfInfo);
// Get signers
int y = 50;
JArray signers = JArray.Parse(info["keys"].ToString());
current = signers.Count;
foreach (string sig in signers)
{
Panel signerInfo = new Panel();
signerInfo.Width = panelSigners.Width - SystemInformation.VerticalScrollBarWidth;
signerInfo.Height = 50;
signerInfo.Location = new Point(0, y);
signerInfo.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]);
signerInfo.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]);
signerInfo.BorderStyle = BorderStyle.FixedSingle;
Label signerLabel = new Label();
signerLabel.Text = "Signer";
signerLabel.Location = new Point(10, 10);
signerLabel.AutoSize = true;
signerInfo.Controls.Add(signerLabel);
Label signerKey = new Label();
string signerKeyShort = sig.Substring(0, 10) + "..." + sig.Substring(sig.Length - 10);
signerKey.Text = signerKeyShort;
signerKey.Location = new Point(10, 30);
signerKey.AutoSize = true;
signerInfo.Controls.Add(signerKey);
Button DelSignerKey = new Button();
DelSignerKey.Text = "Remove";
DelSignerKey.AutoSize = true;
DelSignerKey.FlatStyle = FlatStyle.Flat;
DelSignerKey.Location = new Point(signerInfo.Width - DelSignerKey.Width - 10, 10);
DelSignerKey.Click += (s, e) =>
{
RemoveSig(sig);
};
signerInfo.Controls.Add(DelSignerKey);
panelSigners.Controls.Add(signerInfo);
y += 50;
}
}
private async Task RemoveSig(string sig)
{
string path = "wallet/" + mainForm.Account + "/shared-key";
string content = "{\"accountKey\": \"" + sig + "\",\"account\":\"default\"}";
string resp = await APIPut(path, true, content);
UpdateInfo();
}
private async Task AddSigAsync(string sig)
{
string path = "wallet/" + mainForm.Account + "/shared-key";
string content = "{\"accountKey\": \"" + sig + "\",\"account\":\"default\"}";
string resp = await APIPut(path, true, content);
UpdateInfo();
}
private async void buttoAddSigner_Click(object sender, EventArgs e)
{
if (textBoxAddSig.Text.Length < 5)
{
NotifyForm notifyForm = new NotifyForm("You need to add a XPUB key");
notifyForm.ShowDialog();
notifyForm.Dispose();
return;
}
await AddSigAsync(textBoxAddSig.Text);
textBoxAddSig.Text = "";
}
HttpClient httpClient = new HttpClient();
/// <summary>
/// Put to HSD API
/// </summary>
/// <param name="path">Path to put to</param>
/// <param name="wallet">Whether to use port 12039</param>
/// <param name="content">Content to put</param>
/// <returns></returns>
public async Task<string> APIPut(string path, bool wallet, string content)
{
if (content == "{\"passphrase\": \"\",\"timeout\": 60}")
{
return "";
}
string key = mainForm.NodeSettings["Key"];
string ip = mainForm.NodeSettings["IP"];
string port = "1203";
if (mainForm.HSDNetwork == 1)
{
port = "1303";
}
if (wallet) port = port + "9";
else port = port + "7";
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Put, "http://" + ip + ":" + port + "/" + path);
req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("x:" + key)));
req.Content = new StringContent(content);
// Send request
try
{
HttpResponseMessage resp = await httpClient.SendAsync(req);
if (!resp.IsSuccessStatusCode)
{
mainForm.AddLog("Post Error: " + resp.StatusCode);
mainForm.AddLog(await resp.Content.ReadAsStringAsync());
return "Error";
}
return await resp.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
mainForm.AddLog("Post Error: " + ex.Message);
return "Error";
}
}
private void textBoxAddSig_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
buttoAddSigner_Click(sender, e);
e.SuppressKeyPress = true;
}
}
}
}

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

@ -46,9 +46,18 @@
label2 = new Label(); label2 = new Label();
groupBoxSeed = new GroupBox(); groupBoxSeed = new GroupBox();
textBoxSeedPhrase = new TextBox(); textBoxSeedPhrase = new TextBox();
groupBoxMulti = new GroupBox();
numericUpDownM = new NumericUpDown();
numericUpDownN = new NumericUpDown();
label7 = new Label();
label6 = new Label();
checkBoxMulti = new CheckBox();
groupBoxMode.SuspendLayout(); groupBoxMode.SuspendLayout();
groupBoxNew.SuspendLayout(); groupBoxNew.SuspendLayout();
groupBoxSeed.SuspendLayout(); groupBoxSeed.SuspendLayout();
groupBoxMulti.SuspendLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownM).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownN).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// buttonNext // buttonNext
@ -241,11 +250,74 @@
textBoxSeedPhrase.Size = new Size(438, 288); textBoxSeedPhrase.Size = new Size(438, 288);
textBoxSeedPhrase.TabIndex = 0; textBoxSeedPhrase.TabIndex = 0;
// //
// groupBoxMulti
//
groupBoxMulti.Controls.Add(numericUpDownM);
groupBoxMulti.Controls.Add(numericUpDownN);
groupBoxMulti.Controls.Add(label7);
groupBoxMulti.Controls.Add(label6);
groupBoxMulti.Controls.Add(checkBoxMulti);
groupBoxMulti.Location = new Point(125, 22);
groupBoxMulti.Name = "groupBoxMulti";
groupBoxMulti.Size = new Size(450, 319);
groupBoxMulti.TabIndex = 6;
groupBoxMulti.TabStop = false;
groupBoxMulti.Text = "Multisig";
//
// numericUpDownM
//
numericUpDownM.Location = new Point(223, 91);
numericUpDownM.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownM.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownM.Name = "numericUpDownM";
numericUpDownM.Size = new Size(120, 23);
numericUpDownM.TabIndex = 2;
numericUpDownM.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// numericUpDownN
//
numericUpDownN.Location = new Point(223, 55);
numericUpDownN.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownN.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownN.Name = "numericUpDownN";
numericUpDownN.Size = new Size(120, 23);
numericUpDownN.TabIndex = 2;
numericUpDownN.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// label7
//
label7.AutoSize = true;
label7.Location = new Point(6, 93);
label7.Name = "label7";
label7.Size = new Size(211, 15);
label7.TabIndex = 1;
label7.Text = "Required Signers to send a transaction:";
//
// label6
//
label6.AutoSize = true;
label6.Location = new Point(141, 61);
label6.Name = "label6";
label6.Size = new Size(76, 15);
label6.TabIndex = 1;
label6.Text = "Total Signers:";
//
// checkBoxMulti
//
checkBoxMulti.AutoSize = true;
checkBoxMulti.Location = new Point(6, 23);
checkBoxMulti.Name = "checkBoxMulti";
checkBoxMulti.Size = new Size(115, 19);
checkBoxMulti.TabIndex = 0;
checkBoxMulti.Text = "Create a multisig";
checkBoxMulti.UseVisualStyleBackColor = true;
//
// NewAccountForm // NewAccountForm
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(680, 430); ClientSize = new Size(680, 430);
Controls.Add(groupBoxMulti);
Controls.Add(groupBoxSeed); Controls.Add(groupBoxSeed);
Controls.Add(buttonCancel); Controls.Add(buttonCancel);
Controls.Add(buttonNext); Controls.Add(buttonNext);
@ -263,6 +335,10 @@
groupBoxNew.PerformLayout(); groupBoxNew.PerformLayout();
groupBoxSeed.ResumeLayout(false); groupBoxSeed.ResumeLayout(false);
groupBoxSeed.PerformLayout(); groupBoxSeed.PerformLayout();
groupBoxMulti.ResumeLayout(false);
groupBoxMulti.PerformLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownM).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownN).EndInit();
ResumeLayout(false); ResumeLayout(false);
} }
@ -285,5 +361,11 @@
private Label label5; private Label label5;
private GroupBox groupBoxSeed; private GroupBox groupBoxSeed;
private TextBox textBoxSeedPhrase; private TextBox textBoxSeedPhrase;
private GroupBox groupBoxMulti;
private CheckBox checkBoxMulti;
private NumericUpDown numericUpDownM;
private NumericUpDown numericUpDownN;
private Label label7;
private Label label6;
} }
} }

View File

@ -1,17 +1,7 @@
using System; using System.Diagnostics;
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;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using Newtonsoft.Json.Linq;
using System.Windows.Forms;
using Microsoft.VisualBasic.Devices;
namespace FireWallet namespace FireWallet
{ {
@ -27,14 +17,14 @@ namespace FireWallet
private void NewAccountForm_Load(object sender, EventArgs e) private void NewAccountForm_Load(object sender, EventArgs e)
{ {
page = 0; page = 0;
Dictionary<string, string> theme = mainForm.theme; Dictionary<string, string> theme = mainForm.Theme;
this.BackColor = ColorTranslator.FromHtml(theme["background"]); this.BackColor = ColorTranslator.FromHtml(theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(theme["foreground"]); this.ForeColor = ColorTranslator.FromHtml(theme["foreground"]);
foreach (Control c in Controls) foreach (Control c in Controls)
{ {
mainForm.ThemeControl(c); mainForm.ThemeControl(c);
} }
groupBoxMulti.Hide();
} }
@ -148,53 +138,179 @@ namespace FireWallet
if (page == 1) if (page == 1)
{ {
// Create new wallet groupBoxMulti.Show();
buttonNext.Enabled = false; page = 6;
string path = "wallet/" + textBoxNewName.Text;
string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\"}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error creating wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Created wallet: " + textBoxNewName.Text);
NotifyForm notify2 = new NotifyForm("Created wallet: " + textBoxNewName.Text);
notify2.ShowDialog();
notify2.Dispose();
this.Close();
} }
else if (page == 2) else if (page == 2)
{ {
groupBoxSeed.Show(); groupBoxSeed.Show();
buttonNext.Text = "Import";
page = 3; page = 3;
} }
else if (page == 3) else if (page == 3)
{ {
// Create new wallet page = 5;
buttonNext.Enabled = false; groupBoxMulti.Show();
string path = "wallet/" + textBoxNewName.Text; buttonNext.Text = "Import";
string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\"}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error creating wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Created wallet: " + textBoxNewName.Text);
NotifyForm notify2 = new NotifyForm("Imported wallet: " + textBoxNewName.Text);
notify2.ShowDialog();
notify2.Dispose();
this.Close();
} }
else if (page == 5)
{
if (!checkBoxMulti.Checked)
{
// Import wallet from seed
buttonNext.Enabled = false;
string path = "wallet/" + textBoxNewName.Text;
string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\"}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error creating wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Created wallet: " + textBoxNewName.Text);
NotifyForm notify2 = new NotifyForm("Imported wallet: " + textBoxNewName.Text);
notify2.ShowDialog();
notify2.Dispose();
this.Close();
}
else
{
// Import wallet from seed and create multisig
buttonNext.Enabled = false;
string path = "wallet/" + textBoxNewName.Text;
string content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\",\"mnemonic\":\"" + textBoxSeedPhrase.Text + "\", \"type\":\"multisig\",\"m\":"+numericUpDownM.Value.ToString()+ ",\"n\":" +numericUpDownN.Value.ToString() + "}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error creating wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Created wallet: " + textBoxNewName.Text);
NotifyForm notify2 = new NotifyForm("Imported wallet: " + textBoxNewName.Text);
notify2.ShowDialog();
notify2.Dispose();
this.Close();
}
}
else if (page == 6)
{
if (!checkBoxMulti.Checked)
{
// Create new wallet
buttonNext.Enabled = false;
string path = "wallet/" + textBoxNewName.Text;
string content = "{}";
//content = "{\"passphrase\":\"" + textBoxNewPass1.Text + "\"}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error creating wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Created wallet: " + textBoxNewName.Text);
// Show SEED PHRASE
path = "wallet/" + textBoxNewName.Text + "/master";
response = await mainForm.APIGet(path, true);
JObject resp = JObject.Parse(response);
if (resp["encrypted"].ToString() == "False")
{
JObject mnemonic = JObject.Parse(resp["mnemonic"].ToString());
string phrase = mnemonic["phrase"].ToString();
NotifyForm notifyForm = new NotifyForm("SEED PHRASE\nSTORE THIS SOMEWHERE SECURE\n" + phrase, "Copy", phrase, true);
notifyForm.ShowDialog();
notifyForm.Dispose();
}
// Select wallet
content = "{\"method\":\"selectwallet\",\"params\":[\"" + textBoxNewName.Text + "\"]}";
response = await mainForm.APIPost("", true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error selecting wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
// Encrypt wallet
content = "{\"method\":\"encryptwallet\",\"params\":[\"" + textBoxNewPass1.Text + "\"]}";
response = await mainForm.APIPost("", true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error encrypting wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Encrypted wallet: " + textBoxNewName.Text);
this.Close();
} else
{
// Create new wallet
buttonNext.Enabled = false;
string path = "wallet/" + textBoxNewName.Text;
string content = "{\"type\":\"multisig\",\"m\":"+numericUpDownM.Value.ToString()+ ",\"n\":" +numericUpDownN.Value.ToString() + "}";
string response = await APIPut(path, true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error creating wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
path = "wallet/" + textBoxNewName.Text + "/master";
response = await mainForm.APIGet(path, true);
JObject resp = JObject.Parse(response);
if (resp["encrypted"].ToString() == "False")
{
JObject mnemonic = JObject.Parse(resp["mnemonic"].ToString());
string phrase = mnemonic["phrase"].ToString();
NotifyForm notifyForm = new NotifyForm("SEED PHRASE\nSTORE THIS SOMEWHERE SECURE\n" + phrase, "Copy", phrase, true);
notifyForm.ShowDialog();
notifyForm.Dispose();
}
// Select wallet
content = "{\"method\":\"selectwallet\",\"params\":[\"" + textBoxNewName.Text + "\"]}";
response = await mainForm.APIPost("", true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error selecting wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
// Encrypt wallet
content = "{\"method\":\"encryptwallet\",\"params\":[\"" + textBoxNewPass1.Text + "\"]}";
response = await mainForm.APIPost("", true, content);
if (response == "Error")
{
NotifyForm notify = new NotifyForm("Error encrypting wallet");
notify.ShowDialog();
notify.Dispose();
buttonNext.Enabled = true;
return;
}
mainForm.AddLog("Encrypted wallet: " + textBoxNewName.Text);
this.Close();
}
}
else if (page == 4) else if (page == 4)
{ {
try try
@ -208,7 +324,7 @@ namespace FireWallet
proc.StartInfo.UseShellExecute = false; proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "node.exe"; proc.StartInfo.FileName = "node.exe";
proc.StartInfo.Arguments = mainForm.dir + "hsd-ledger/bin/hsd-ledger createwallet " + textBoxNewPass1.Text + " --api-key " + mainForm.nodeSettings["Key"]; proc.StartInfo.Arguments = mainForm.dir + "hsd-ledger/bin/hsd-ledger createwallet " + textBoxNewPass1.Text + " --api-key " + mainForm.NodeSettings["Key"];
var outputBuilder = new StringBuilder(); var outputBuilder = new StringBuilder();
// Event handler for capturing output data // Event handler for capturing output data
@ -228,7 +344,7 @@ namespace FireWallet
} }
catch (Exception ex) catch (Exception ex)
{ {
mainForm.AddLog(ex.Message); mainForm.AddLog(ex.Message);
NotifyForm notify = new NotifyForm("Error importing wallet\n" + ex.Message); NotifyForm notify = new NotifyForm("Error importing wallet\n" + ex.Message);
notify.ShowDialog(); notify.ShowDialog();
notify.Dispose(); notify.Dispose();
@ -243,10 +359,10 @@ namespace FireWallet
HttpClient httpClient = new HttpClient(); HttpClient httpClient = new HttpClient();
private async Task<string> APIPut(string path, bool wallet, string content) private async Task<string> APIPut(string path, bool wallet, string content)
{ {
string key = mainForm.nodeSettings["Key"]; string key = mainForm.NodeSettings["Key"];
string ip = mainForm.nodeSettings["IP"]; string ip = mainForm.NodeSettings["IP"];
string port = "1203"; string port = "1203";
if (mainForm.network == 1) if (mainForm.HSDNetwork == 1)
{ {
port = "1303"; port = "1303";
} }
@ -265,7 +381,8 @@ namespace FireWallet
if (resp.IsSuccessStatusCode) if (resp.IsSuccessStatusCode)
{ {
return await resp.Content.ReadAsStringAsync(); return await resp.Content.ReadAsStringAsync();
} else }
else
{ {
mainForm.AddLog("Put Error: " + await resp.Content.ReadAsStringAsync()); mainForm.AddLog("Put Error: " + await resp.Content.ReadAsStringAsync());
return "Error"; return "Error";

View File

@ -59,5 +59,15 @@ namespace FireWallet.Properties {
resourceCulture = value; resourceCulture = value;
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap FWSplash {
get {
object obj = ResourceManager.GetObject("FWSplash", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
} }
} }

View File

@ -117,4 +117,8 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="FWSplash" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\FWSplash.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -30,19 +30,18 @@
{ {
components = new System.ComponentModel.Container(); components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SplashScreen)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SplashScreen));
timerSplashDelay = new System.Windows.Forms.Timer(components);
label1 = new Label(); label1 = new Label();
pictureBox1 = new PictureBox(); pictureBox1 = new PictureBox();
label2 = new Label(); label2 = new Label();
panelNew = new Panel();
pictureBoxNew = new PictureBox();
timerIn = new System.Windows.Forms.Timer(components);
timerOut = new System.Windows.Forms.Timer(components);
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
panelNew.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBoxNew).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// timerSplashDelay
//
timerSplashDelay.Enabled = true;
timerSplashDelay.Interval = 3000;
timerSplashDelay.Tick += timerSplashDelay_Tick;
//
// label1 // label1
// //
label1.AutoSize = true; label1.AutoSize = true;
@ -75,12 +74,45 @@
label2.Text = "Nathan.Woodburn/"; label2.Text = "Nathan.Woodburn/";
label2.Click += label2_Click; label2.Click += label2_Click;
// //
// panelNew
//
panelNew.Controls.Add(pictureBoxNew);
panelNew.Dock = DockStyle.Fill;
panelNew.Location = new Point(0, 0);
panelNew.Name = "panelNew";
panelNew.Size = new Size(450, 450);
panelNew.TabIndex = 3;
//
// pictureBoxNew
//
pictureBoxNew.BackColor = Color.Black;
pictureBoxNew.Dock = DockStyle.Fill;
pictureBoxNew.Image = Properties.Resources.FWSplash;
pictureBoxNew.InitialImage = null;
pictureBoxNew.Location = new Point(0, 0);
pictureBoxNew.Name = "pictureBoxNew";
pictureBoxNew.Size = new Size(450, 450);
pictureBoxNew.SizeMode = PictureBoxSizeMode.Zoom;
pictureBoxNew.TabIndex = 0;
pictureBoxNew.TabStop = false;
pictureBoxNew.Visible = false;
//
// timerIn
//
timerIn.Enabled = true;
timerIn.Tick += timerIn_Tick;
//
// timerOut
//
timerOut.Tick += timerOut_Tick;
//
// SplashScreen // SplashScreen
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Black; BackColor = Color.Black;
ClientSize = new Size(444, 435); ClientSize = new Size(450, 450);
Controls.Add(panelNew);
Controls.Add(label2); Controls.Add(label2);
Controls.Add(pictureBox1); Controls.Add(pictureBox1);
Controls.Add(label1); Controls.Add(label1);
@ -93,16 +125,21 @@
Text = "FireWallet"; Text = "FireWallet";
TopMost = true; TopMost = true;
FormClosing += SplashScreen_FormClosing; FormClosing += SplashScreen_FormClosing;
Load += SplashScreen_Load;
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
panelNew.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)pictureBoxNew).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
} }
#endregion #endregion
private System.Windows.Forms.Timer timerSplashDelay;
private Label label1; private Label label1;
private PictureBox pictureBox1; private PictureBox pictureBox1;
private Label label2; private Label label2;
private Panel panelNew;
private PictureBox pictureBoxNew;
private System.Windows.Forms.Timer timerIn;
private System.Windows.Forms.Timer timerOut;
} }
} }

View File

@ -1,35 +1,35 @@
using System; using System.Diagnostics;
using System.Collections.Generic; using System.Drawing.Imaging;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FireWallet namespace FireWallet
{ {
public partial class SplashScreen : Form public partial class SplashScreen : Form
{ {
public SplashScreen() public SplashScreen(bool timer)
{ {
InitializeComponent(); InitializeComponent();
close = false; close = false;
IsClosed = false;
} }
bool close; bool close;
private void timerSplashDelay_Tick(object sender, EventArgs e) float opacity = 0.0f;
{
close = true;
this.Close();
}
private void SplashScreen_FormClosing(object sender, FormClosingEventArgs e) private void SplashScreen_FormClosing(object sender, FormClosingEventArgs e)
{ {
if (!close)
{
e.Cancel = true;
}
} }
public bool IsClosed { get; set; }
public void CloseSplash()
{
close = true;
// Fade out
timerIn.Stop();
timerOut.Start();
}
private void label2_Click(object sender, EventArgs e) private void label2_Click(object sender, EventArgs e)
{ {
ProcessStartInfo psi = new ProcessStartInfo ProcessStartInfo psi = new ProcessStartInfo
@ -39,5 +39,56 @@ namespace FireWallet
}; };
Process.Start(psi); Process.Start(psi);
} }
Bitmap splash = new Bitmap(Properties.Resources.FWSplash);
private void SplashScreen_Load(object sender, EventArgs e)
{
pictureBoxNew.Visible = true;
this.TransparencyKey = Color.FromArgb(0, 0, 0);
pictureBoxNew.Invalidate();
}
public Image SetImageOpacity(Image image, float opacity)
{
try
{
Bitmap bmp = new Bitmap(image.Width, image.Height);
using (Graphics gfx = Graphics.FromImage(bmp))
{
ColorMatrix matrix = new ColorMatrix();
matrix.Matrix33 = opacity;
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
gfx.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
}
return bmp;
}
catch
{
return null;
}
}
private void timerIn_Tick(object sender, EventArgs e)
{
if (opacity >= 1)
{
timerIn.Stop();
return;
}
opacity += 0.05f;
pictureBoxNew.Image = SetImageOpacity(splash, opacity);
pictureBoxNew.Invalidate();
}
private void timerOut_Tick(object sender, EventArgs e)
{
if (opacity <= 0)
{
timerOut.Stop();
IsClosed = true;
this.Close();
return;
}
opacity -= 0.05f;
pictureBoxNew.Image = SetImageOpacity(splash, opacity);
pictureBoxNew.Invalidate();
}
} }
} }

View File

@ -117,9 +117,6 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </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" /> <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"> <data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
@ -901,6 +898,12 @@
AAAAAAAAAAAAAADQwWbM+D8RAPjBClJL0gAAAABJRU5ErkJggg== AAAAAAAAAAAAAADQwWbM+D8RAPjBClJL0gAAAABJRU5ErkJggg==
</value> </value>
</data> </data>
<metadata name="timerIn.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="timerOut.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>104, 17</value>
</metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
AAABAAEAAAAAAAEAIAB2pAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAOEAAADAAgGAAAAfG+p9QAAIABJ AAABAAEAAAAAAAEAIAB2pAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAOEAAADAAgGAAAAfG+p9QAAIABJ

View File

@ -17,28 +17,33 @@ namespace FireWallet
{ {
MainForm mainForm; MainForm mainForm;
JObject tx; JObject tx;
public TXForm(MainForm mainForm, JObject tx) string txid;
public TXForm(MainForm mainForm, string txid)
{ {
InitializeComponent(); InitializeComponent();
// Theme // Theme
this.BackColor = ColorTranslator.FromHtml(mainForm.theme["background"]); this.BackColor = ColorTranslator.FromHtml(mainForm.Theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(mainForm.theme["foreground"]); this.ForeColor = ColorTranslator.FromHtml(mainForm.Theme["foreground"]);
foreach (Control c in Controls) foreach (Control c in Controls)
{ {
mainForm.ThemeControl(c); mainForm.ThemeControl(c);
} }
this.mainForm = mainForm; this.mainForm = mainForm;
this.tx = tx; this.txid = txid;
this.Text = "TX: " + tx["hash"].ToString();
} }
private async void TXForm_Load(object sender, EventArgs e) 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(); labelHash.Text = "Hash: " + tx["hash"].ToString();
mainForm.AddLog("Viewing TX: " + 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 // For each input
JArray inputs = (JArray)tx["inputs"]; JArray inputs = (JArray)tx["inputs"];
@ -74,7 +79,7 @@ namespace FireWallet
panelInputs.Controls.Add(PanelInput); panelInputs.Controls.Add(PanelInput);
} }
panelInputs.Visible = true;
// For each output // For each output
JArray outputs = (JArray)tx["outputs"]; JArray outputs = (JArray)tx["outputs"];
foreach (JObject output in outputs) foreach (JObject output in outputs)
@ -131,12 +136,13 @@ namespace FireWallet
panelOutputs.Controls.Add(PanelOutput); panelOutputs.Controls.Add(PanelOutput);
} }
panelOutputs.Visible = true;
} }
private void Explorer_Click(object sender, EventArgs e) private void Explorer_Click(object sender, EventArgs e)
{ {
// Open the transaction in a browser // Open the transaction in a browser
string url = mainForm.userSettings["explorer-tx"] + tx["hash"].ToString(); string url = mainForm.UserSettings["explorer-tx"] + tx["hash"].ToString();
ProcessStartInfo psi = new ProcessStartInfo ProcessStartInfo psi = new ProcessStartInfo
{ {
FileName = url, FileName = url,

View File

@ -36,6 +36,8 @@
label2 = new Label(); label2 = new Label();
textBoxAddress = new TextBox(); textBoxAddress = new TextBox();
labelError = new Label(); labelError = new Label();
labelSendingHIPAddress = new Label();
labelHIPArrow = new Label();
SuspendLayout(); SuspendLayout();
// //
// buttonTransfer // buttonTransfer
@ -105,18 +107,41 @@
// labelError // labelError
// //
labelError.AutoSize = true; labelError.AutoSize = true;
labelError.Location = new Point(46, 139); labelError.Location = new Point(492, 139);
labelError.Name = "labelError"; labelError.Name = "labelError";
labelError.Size = new Size(98, 15); labelError.Size = new Size(98, 15);
labelError.TabIndex = 6; labelError.TabIndex = 6;
labelError.Text = "Address not valid"; labelError.Text = "Address not valid";
labelError.Visible = false; 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 // TransferForm
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(602, 340); ClientSize = new Size(602, 340);
Controls.Add(labelSendingHIPAddress);
Controls.Add(labelHIPArrow);
Controls.Add(labelError); Controls.Add(labelError);
Controls.Add(textBoxAddress); Controls.Add(textBoxAddress);
Controls.Add(label2); Controls.Add(label2);
@ -143,5 +168,7 @@
private Label label2; private Label label2;
private TextBox textBoxAddress; private TextBox textBoxAddress;
private Label labelError; private Label labelError;
private Label labelSendingHIPAddress;
private Label labelHIPArrow;
} }
} }

View File

@ -8,6 +8,8 @@ using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using DnsClient.Protocol;
using DnsClient;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace FireWallet namespace FireWallet
@ -23,18 +25,18 @@ namespace FireWallet
Domain = domain; Domain = domain;
this.Text = "Transfer " + Domain + " | FireWallet"; this.Text = "Transfer " + Domain + " | FireWallet";
label1.Text = "Transfer " + Domain; 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 buttonTransfer.Enabled = false; // watch only wallet only batch
} }
// Theme // Theme
this.BackColor = ColorTranslator.FromHtml(MainForm.theme["background"]); this.BackColor = ColorTranslator.FromHtml(MainForm.Theme["background"]);
this.ForeColor = ColorTranslator.FromHtml(MainForm.theme["foreground"]); this.ForeColor = ColorTranslator.FromHtml(MainForm.Theme["foreground"]);
foreach (Control c in Controls) foreach (Control c in Controls)
{ {
MainForm.ThemeControl(c); MainForm.ThemeControl(c);
@ -46,16 +48,19 @@ namespace FireWallet
this.Close(); this.Close();
} }
string address = "";
private async void buttonTransfer_Click(object sender, EventArgs e) private async void buttonTransfer_Click(object sender, EventArgs e)
{ {
if (!await MainForm.ValidAddress(textBoxAddress.Text)) await updateAddress();
if (!await MainForm.ValidAddress(address))
{ {
labelError.Show(); labelError.Show();
return; return;
} }
string content = "{\"method\": \"sendtransfer\",\"params\": [ \"" + Domain + "\", \"" + string content = "{\"method\": \"sendtransfer\",\"params\": [ \"" + Domain + "\", \"" +
textBoxAddress.Text + "\"]}"; address + "\"]}";
string output = await MainForm.APIPost("", true, content); string output = await MainForm.APIPost("", true, content);
JObject APIresp = JObject.Parse(output); JObject APIresp = JObject.Parse(output);
if (APIresp["error"].ToString() != "") if (APIresp["error"].ToString() != "")
@ -68,7 +73,7 @@ namespace FireWallet
} }
JObject result = JObject.Parse(APIresp["result"].ToString()); JObject result = JObject.Parse(APIresp["result"].ToString());
string hash = result["hash"].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", NotifyForm notifySuccess = new NotifyForm("Transaction Sent\nThis transaction could take up to 20 minutes to mine",
"Explorer", link); "Explorer", link);
notifySuccess.ShowDialog(); notifySuccess.ShowDialog();
@ -78,14 +83,48 @@ namespace FireWallet
private async void buttonBatch_Click(object sender, EventArgs e) private async void buttonBatch_Click(object sender, EventArgs e)
{ {
if (!await MainForm.ValidAddress(textBoxAddress.Text)) await updateAddress();
if (!await MainForm.ValidAddress(address))
{ {
labelError.Show(); labelError.Show();
return; return;
} }
MainForm.AddBatch(Domain, "TRANSFER", textBoxAddress.Text); MainForm.AddBatch(Domain, "TRANSFER", address);
this.Close(); this.Close();
} }
private async Task updateAddress()
{
labelError.Hide();
if (textBoxAddress.Text.Length < 1)
{
address = "";
return;
}
if (textBoxAddress.Text.Substring(0, 1) == "@")
{
string domain = textBoxAddress.Text.Substring(1);
string address = await MainForm.HIP02Lookup(domain);
if (address == "ERROR")
{
labelError.Show();
labelError.Text = "HIP-02 lookup failed";
} else
{
labelSendingHIPAddress.Text = address;
this.address = address;
labelSendingHIPAddress.Show();
labelHIPArrow.Show();
}
} else
{
address = textBoxAddress.Text;
}
}
} }
} }

BIN
FireWallet/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -224,15 +224,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:FireWallet" "ProductName" = "8:FireWallet"
"ProductCode" = "8:{D203173F-39CF-4D8C-810D-FF6840540AF3}" "ProductCode" = "8:{E904E664-B1F3-4DEB-9FB0-91BCBEE3B5A6}"
"PackageCode" = "8:{419FAC68-35FF-48D7-AD7D-83813C7CF72A}" "PackageCode" = "8:{0B16637D-C5AC-41D4-9D13-D57F3A0AEF25}"
"UpgradeCode" = "8:{0C86F725-6B01-4173-AA05-3F0EDF481362}" "UpgradeCode" = "8:{0C86F725-6B01-4173-AA05-3F0EDF481362}"
"AspNetVersion" = "8:" "AspNetVersion" = "8:"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:2.5" "ProductVersion" = "8:4.0"
"Manufacturer" = "8:Nathan.Woodburn/" "Manufacturer" = "8:Nathan.Woodburn/"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:https://l.woodburn.au/discord" "ARPHELPLINK" = "8:https://l.woodburn.au/discord"

View File

@ -1,7 +1,17 @@
# FireWallet # FireWallet
Experimental wallet for Handshake chain Experimental wallet for Handshake chain
The newer python version is available [here](https://github.com/nathanwoodburn/firewalletbrowser)
Info about the project can be found at https://firewallet or https://firewallet.au
## Installation ## 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 ### From Releases
You can install the latest release from [here](https://github.com/Nathanwoodburn/FireWallet/releases/). You can install the latest release from [here](https://github.com/Nathanwoodburn/FireWallet/releases/).
@ -60,6 +70,9 @@ You can change the number of transactions shown in the `portfolio-tx:` settings.
<br><br> <br><br>
## Sending HNS ## Sending HNS
![Send](assets/send_hns.png) ![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 ## Receiving HNS or Domains
The receive page shows your current HNS address. The receive page shows your current HNS address.
@ -102,8 +115,7 @@ You can add transactions to the batch from the domain window or the DNS editor.
You can also import a list of domains to the batch window. You can also import a list of domains to the batch window.
The "CANCEL" transaction type is used to cancel an transfer. 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) ![Batch Import](assets/batch_import.png)
## Exporting ## Exporting
@ -128,12 +140,33 @@ They are stored in `%appdata%\FireWallet\` (`C:\Users\{username}\AppData\Roaming
## settings.txt ## settings.txt
This file stores the user settings for the application. This file stores the user settings for the application.
If you want to change the default HIP-02 resolver you can add these settings
```yaml
hip-02-ip: 127.0.0.1
hip-02-port: 5350
```
## node.txt ## node.txt
This file stores the node (HSD/Bob connection) settings. This file stores the node (HSD/Bob connection) settings.
The Network is the network you want to connect to (default is `0` for Mainnet). 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. 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.
Other settings are here. These are the default and if they are not in the file they revert to these values.
```yaml
HideScreen: True # Hide the HSD terminal screen (Set to False for higher reliability)
Timeout: 10 # The time in seconds to wait for any API request
```
## theme.txt ## theme.txt
This file stores the theme settings. This file stores the theme settings.
The theme is the color scheme of the application. The theme is the color scheme of the application.
@ -143,3 +176,14 @@ There are 4 modes: `off` is disabled, `mica` is windows app style, `key` is to m
## log.txt ## log.txt
This file stores the logs for the application. This file stores the logs for the application.
You should check this file if you have any issues with the application. You should check this file if you have any issues with the application.
# Thanks
Thanks to @ponderingken (https://github.com/ponderingken) for designing the logo and splash screen.
# 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.
Also you can send HNS directly to `@firewallet`

View File

@ -6,4 +6,4 @@ woodburn4,BID,1,3
woodburn5,BID,1,3 woodburn5,BID,1,3
woodburn6,BID,1,4 woodburn6,BID,1,4
woodburn8,TRANSFER,hs1qlmlgnx0g3ynk4ylxkkdh9c9nernclnfq4lw6s9 woodburn8,TRANSFER,hs1qlmlgnx0g3ynk4ylxkkdh9c9nernclnfq4lw6s9
exampledomainnathan118,UPDATE,[{"type": "DS","keyTag": 20167,"algorithm": 13,"digestType": 2,"digest":"4a2ab3224727a4754a6c3d77621a5b04241a3d9c7ae7e5fa17f73121b9ff0e06"}, {"type": "NS","ns": "ns1.woodburn."}, {"type": "NS","ns": "ns2.woodburn."}, {"type": "TXT","txt": ["TEST"]}] exampledomainnathan90,UPDATE,[{"type": "NS","ns": "ns1.woodburn."};{"type": "NS","ns": "ns2.woodburn."};{"type": "DS","keyTag": 30273,"algorithm": 13,"digestType": 2,"digest":"9a3a8fb3d625d2a2073d740f10da6056ebed0e97f550aa7f3891ed450c7e60c9"};{"type": "GLUE4","ns": "ns1.exampledomainnathan90.","address": "1.2.3.4"};{"type": "TXT","txt": ["Test TXT record"]}]

View File

@ -1,3 +1,5 @@
IP: 127.0.0.1 IP: 127.0.0.1
Network: 0 Network: 0
Key: my-super-secret-api-key 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 network = Network.get(config.str('network')); // Get the network
const id = config.str('wallet-id'); // Get the wallet id const id = config.str('wallet-id'); // Get the wallet id
const acct = config.str('account-name'); // Get the account name const acct = config.str('account-name'); // Get the account name
const batch = args[0]; // Get the batch file location // Log the arguments to the console (for debugging)
const nameslocation = args[1]; // Get the names file location
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 await wclient.execute('selectwallet', [id]); // Select the wallet
const fs = require('fs'); // Import fs (used to read files)
try { try {
const data = fs.readFileSync(batch, 'utf8'); // Read the batch file const mtx = MTX.fromJSON(batch.result); // Create a new MTX from the JSON
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 hashes = {}; // Create an empty object to store the hashes const hashes = {}; // Create an empty object to store the hashes
for (const name of names) { // Loop through the names for (const name of names) { // Loop through the names
const hash = hashName(name); // Hash the name 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 createaccount <account-name> <account-index>');
console.log(' $ hsd-ledger createaddress'); console.log(' $ hsd-ledger createaddress');
console.log(' $ hsd-ledger sendtoaddress <address> <amount>'); console.log(' $ hsd-ledger sendtoaddress <address> <amount>');
console.log(' $ hsd-ledger sendraw <batch> <names>');
console.log(' $ hsd-ledger getwallets'); console.log(' $ hsd-ledger getwallets');
console.log(' $ hsd-ledger getaccounts'); console.log(' $ hsd-ledger getaccounts');
console.log(' $ hsd-ledger getaccount <account-name>'); console.log(' $ hsd-ledger getaccount <account-name>');