mirror of
https://github.com/Nathanwoodburn/FireWallet.git
synced 2024-12-25 15:28:15 +11:00
multisig: Added multisig from batching
This commit is contained in:
parent
db5934bf4a
commit
f69f16df4a
@ -29,6 +29,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DnsClient" Version="1.7.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace FireWallet
|
||||
{
|
||||
@ -10,15 +11,25 @@ namespace FireWallet
|
||||
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;
|
||||
@ -31,25 +42,28 @@ namespace FireWallet
|
||||
{
|
||||
mainForm.ThemeControl(c);
|
||||
}
|
||||
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||||
openFileDialog.Filter = "Transaction files (*.json)|*.json";
|
||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||
if (tx == null)
|
||||
{
|
||||
string tx = System.IO.File.ReadAllText(openFileDialog.FileName);
|
||||
try
|
||||
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||||
openFileDialog.Filter = "Transaction files (*.json)|*.json";
|
||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
JObject txObj = JObject.Parse(tx);
|
||||
this.tx = txObj;
|
||||
ParseTX();
|
||||
}
|
||||
catch
|
||||
{
|
||||
NotifyForm notifyForm = new NotifyForm("Invalid transaction file.");
|
||||
notifyForm.ShowDialog();
|
||||
notifyForm.Dispose();
|
||||
this.Close();
|
||||
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 Cancelbutton2_Click(object sender, EventArgs e)
|
||||
@ -230,9 +244,6 @@ namespace FireWallet
|
||||
{
|
||||
if (metaOutput.ContainsKey("name"))
|
||||
{
|
||||
|
||||
|
||||
|
||||
Label covenantLabel = new Label();
|
||||
string name = metaOutput["name"].ToString();
|
||||
|
||||
@ -240,6 +251,14 @@ namespace FireWallet
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,12 +307,14 @@ namespace FireWallet
|
||||
labelSigsSigned.Width = (labelSigsTotal.Width / totalSigs) * sigs;
|
||||
labelSigInfo.Text = "Signed: " + sigs + "\nReq: " + reqSigs + " of " + totalSigs;
|
||||
signedTX = response;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonExport_Click(object sender, EventArgs e)
|
||||
{
|
||||
mainForm.ExportTransaction(signedTX);
|
||||
mainForm.ExportTransaction(signedTX,domains);
|
||||
}
|
||||
|
||||
private async void buttonSend_Click(object sender, EventArgs e)
|
||||
|
@ -6,6 +6,7 @@ using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using DnsClient;
|
||||
using DnsClient.Protocol;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@ -1982,6 +1983,26 @@ namespace FireWallet
|
||||
}
|
||||
ExportTransaction(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
string content = "{\"method\": \"createsendtoaddress\",\"params\": [ \"" + address + "\", " +
|
||||
amount.ToString() + ", \"\", \"\", " + subtractFee + " ]}";
|
||||
string output = await APIPost("", true, content);
|
||||
JObject APIresp = JObject.Parse(output);
|
||||
if (APIresp["error"].ToString() != "")
|
||||
{
|
||||
AddLog("Failed:");
|
||||
AddLog(APIresp.ToString());
|
||||
JObject error = JObject.Parse(APIresp["error"].ToString());
|
||||
string ErrorMessage = error["message"].ToString();
|
||||
|
||||
NotifyForm notify = new NotifyForm("Error Transaction Failed\n" + ErrorMessage);
|
||||
notify.ShowDialog();
|
||||
return;
|
||||
}
|
||||
string signed = signRaw(output,new string[0]);
|
||||
ExportTransaction(signed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -2521,6 +2542,7 @@ namespace FireWallet
|
||||
BatchMode = true;
|
||||
}
|
||||
BatchForm.AddBatch(domain, operation);
|
||||
BatchForm.UpdateTheme();
|
||||
|
||||
}
|
||||
public void AddBatch(string domain, string operation, decimal bid, decimal lockup)
|
||||
@ -2533,6 +2555,7 @@ namespace FireWallet
|
||||
BatchMode = true;
|
||||
}
|
||||
BatchForm.AddBatch(domain, operation, bid, lockup);
|
||||
BatchForm.UpdateTheme();
|
||||
|
||||
}
|
||||
public void AddBatch(string domain, string operation, DNS[] updateRecords)
|
||||
@ -2544,6 +2567,7 @@ namespace FireWallet
|
||||
BatchMode = true;
|
||||
}
|
||||
BatchForm.AddBatch(domain, operation, updateRecords);
|
||||
BatchForm.UpdateTheme();
|
||||
}
|
||||
public void AddBatch(string domain, string operation, string address)
|
||||
{
|
||||
@ -2554,6 +2578,7 @@ namespace FireWallet
|
||||
BatchMode = true;
|
||||
}
|
||||
BatchForm.AddBatch(domain, operation, address);
|
||||
BatchForm.UpdateTheme();
|
||||
}
|
||||
public void FinishBatch()
|
||||
{
|
||||
@ -2699,7 +2724,11 @@ namespace FireWallet
|
||||
|
||||
|
||||
#region Multi
|
||||
public void ExportTransaction(string rawTX)
|
||||
public async Task<string> ExportTransaction(string rawTX)
|
||||
{
|
||||
return await ExportTransaction(rawTX, new string[0]);
|
||||
}
|
||||
public async Task<string> ExportTransaction(string rawTX, string[] domains)
|
||||
{
|
||||
JObject tx = JObject.Parse(rawTX);
|
||||
JObject toExport = new JObject();
|
||||
@ -2709,6 +2738,14 @@ namespace FireWallet
|
||||
JArray outputsParsed = new JArray();
|
||||
JArray inputs = JArray.Parse(tx["inputs"].ToString());
|
||||
JArray outputs = JArray.Parse(tx["outputs"].ToString());
|
||||
|
||||
Dictionary<string,string> hashes = new Dictionary<string, string>();
|
||||
foreach (string domain in domains)
|
||||
{
|
||||
// sha3 hash of domain
|
||||
hashes.Add(CalculateSHA3Hash(domain),domain);
|
||||
}
|
||||
|
||||
foreach (JObject input in inputs)
|
||||
{
|
||||
JObject coin = JObject.Parse(input["coin"].ToString());
|
||||
@ -2722,6 +2759,7 @@ namespace FireWallet
|
||||
else
|
||||
{
|
||||
AddLog("Not supported yet");
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
foreach (JObject output in outputs)
|
||||
@ -2735,7 +2773,20 @@ namespace FireWallet
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog("Not supported yet");
|
||||
AddLog(covenant.ToString());
|
||||
string hash = covenant["items"][0].ToString();
|
||||
if (hashes.ContainsKey(hash))
|
||||
{
|
||||
data["name"] = hashes[hash];
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog("Cannot find name for hash " + hash);
|
||||
return "Error";
|
||||
}
|
||||
|
||||
//data["name"];
|
||||
outputsParsed.Add(data);
|
||||
}
|
||||
}
|
||||
JObject metadata = new JObject();
|
||||
@ -2753,8 +2804,81 @@ namespace FireWallet
|
||||
StreamWriter sw = new StreamWriter(saveFileDialog.FileName);
|
||||
sw.Write(toExport.ToString());
|
||||
sw.Dispose();
|
||||
return toExport.ToString();
|
||||
}else
|
||||
{
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
public string signRaw(string tx, string[] domains)
|
||||
{
|
||||
string domainslist = string.Join(",", domains.Select(domain => "\\\"" + domain + "\\\""));
|
||||
NotifyForm notify = new NotifyForm("Please confirm the transaction on your Ledger device", false);
|
||||
notify.Show();
|
||||
|
||||
var proc = new Process();
|
||||
proc.StartInfo.CreateNoWindow = true;
|
||||
proc.StartInfo.RedirectStandardInput = true;
|
||||
proc.StartInfo.RedirectStandardOutput = true;
|
||||
proc.StartInfo.UseShellExecute = false;
|
||||
proc.StartInfo.RedirectStandardError = true;
|
||||
proc.StartInfo.FileName = "node.exe";
|
||||
proc.StartInfo.WorkingDirectory = dir + "hsd-ledger/bin/";
|
||||
string args = "hsd-ledger/bin/hsd-ledger signraw \"\"" + tx.Replace("\"", "\\\"").Trim() + "\"\" [" + domainslist + "] --api-key " + NodeSettings["Key"] + " -w " + Account;
|
||||
AddLog(args);
|
||||
|
||||
proc.StartInfo.Arguments = dir + args;
|
||||
var outputBuilder = new StringBuilder();
|
||||
|
||||
// Event handler for capturing output data
|
||||
proc.OutputDataReceived += (sender, args) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(args.Data))
|
||||
{
|
||||
outputBuilder.AppendLine(args.Data);
|
||||
}
|
||||
};
|
||||
|
||||
proc.Start();
|
||||
proc.BeginOutputReadLine();
|
||||
proc.WaitForExit();
|
||||
|
||||
notify.CloseNotification();
|
||||
notify.Dispose();
|
||||
|
||||
string output = outputBuilder.ToString();
|
||||
AddLog(output);
|
||||
if (output.Length > 2)
|
||||
{
|
||||
// Signed
|
||||
return output;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog(args);
|
||||
AddLog(proc.StandardError.ReadToEnd());
|
||||
NotifyForm notifyError = new NotifyForm("Error sign Failed\nCheck logs for more details");
|
||||
notifyError.ShowDialog();
|
||||
notifyError.Dispose();
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
static string CalculateSHA3Hash(string input)
|
||||
{
|
||||
var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(256);
|
||||
|
||||
// Choose correct encoding based on your usecase
|
||||
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
|
||||
hashAlgorithm.BlockUpdate(inputBytes, 0, inputBytes.Length);
|
||||
|
||||
byte[] result = new byte[256/8];
|
||||
hashAlgorithm.DoFinal(result, 0);
|
||||
|
||||
string hashString = BitConverter.ToString(result);
|
||||
hashString = hashString.Replace("-", "").ToLowerInvariant();
|
||||
return hashString;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user