Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .vs/BitNav/DesignTimeBuild/.dtbcache.v2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified .vs/BitNav/v17/.suo
Binary file not shown.
7 changes: 7 additions & 0 deletions BitNav/Bitcoin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,12 @@ private int GenerateRandomInteger()
}
}

private long ConvertBitcoinToSatoshis(double bitcoinAmount)
{
const long satoshisPerBitcoin = 100_000_000;
return (long)(bitcoinAmount * satoshisPerBitcoin);
}


}
}
195 changes: 195 additions & 0 deletions BitNav/Transaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Transactions;

namespace BitNav
{
public class Transaction
{
private object coin;
private int amount;
private string address;
private string transactionHash;
private long creationTime;
private long receivedTime;
private long confirmationTime;
private WebClient wc;
public event EventHandler<TransactionEventArgs> TransactionReceived;
public event EventHandler<TransactionEventArgs> TransactionConfirmed;

public Transaction(object coin, int amount, string address)
{
this.coin = coin;
this.amount = amount;
this.address = address;
this.transactionHash = null;
this.wc = new WebClient();
this.creationTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
}

//returns true if transaction is received and sets the transaction hash
public bool checkTransactionReceived()
{
if (transactionHash != null)
{
return true;
}
string url = "";
switch(coin)
{
case Bitcoin:
url = "https://api.blockcypher.com/v1/btc/main/addrs/"+address+"/full";
break;
default:
throw new Exception("Invalid coin type");
break;
}

string json = wc.DownloadString(url);
JsonDocument doc = JsonDocument.Parse(json);
JsonElement root = doc.RootElement;
JsonElement txs = root.GetProperty("txrefs");

foreach (JsonElement tx in txs.EnumerateArray())
{

string dateString = tx.GetProperty("received").GetString();
DateTime dateTime = DateTime.ParseExact(dateString, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
long unixTime = ((DateTimeOffset)dateTime).ToUnixTimeSeconds();
if (unixTime >= creationTime)
{
JsonElement txAmount = tx.GetProperty("outputs");
foreach (JsonElement txAmounts in txAmount.EnumerateArray())
{
Console.WriteLine(txAmounts.GetProperty("addresses").GetString());
if (txAmounts.GetProperty("addresses").GetString() == address)
{
if (checkEqualWithMargin(amount, txAmounts.GetProperty("value").GetInt32(), 0))
{
transactionHash = tx.GetProperty("tx_hash").GetString();
receivedTime = unixTime;
OnTransactionReceived();
//checks if confirmation time exists and parses it if it does
try
{
string confirmedString = tx.GetProperty("confirmed").GetString();
DateTime confirmeDateTime = DateTime.ParseExact(confirmedString, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
this.confirmationTime = ((DateTimeOffset)confirmeDateTime).ToUnixTimeSeconds();
OnTransactionConfirmed();
}
catch
{
}
return true;
}
}
}
}
else
{
break;
}
}


return false;
}

public bool checkTransactionConfirmed()
{
if (confirmationTime != 0)
{
return true;
}
else if (transactionHash == null)
{
checkTransactionReceived();

return confirmationTime != 0;
}
string url = "";
switch (coin)
{
case Bitcoin:
url = "https://api.blockcypher.com/v1/btc/main/txs/" + transactionHash;
break;
default:
throw new Exception("Invalid coin type");
break;
}

string json = wc.DownloadString(url);
JsonDocument doc = JsonDocument.Parse(json);
JsonElement root = doc.RootElement;
try
{
string confirmedString = root.GetProperty("confirmed").GetString();
DateTime confirmeDateTime = DateTime.ParseExact(confirmedString, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
this.confirmationTime = ((DateTimeOffset)confirmeDateTime).ToUnixTimeSeconds();
OnTransactionConfirmed();
return true;
}
catch (Exception e)
{
}

return false;
}

private bool checkEqualWithMargin(int a, int b, int margin)
{
return a >= b - margin && a <= b + margin;
}
//returns null if transaction is not received or the transaction hash if it is
public string getTransactionHash()
{
return transactionHash;
}

public string getReceiverAddress()
{
return address;
}

public long getCreationTime()
{
return creationTime;
}

public long getReceivedTime()
{
return receivedTime;
}

public long getConfirmationTime()
{
return confirmationTime;
}
public int getAmount()
{
return amount;
}
public object getCoin()
{
return coin;
}

private void OnTransactionReceived()
{
TransactionReceived?.Invoke(this, new TransactionEventArgs(this));
}
private void OnTransactionConfirmed()
{
TransactionConfirmed?.Invoke(this, new TransactionEventArgs(this));
}

}
}
18 changes: 18 additions & 0 deletions BitNav/TransactionEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BitNav
{
public class TransactionEventArgs : EventArgs
{
public Transaction Transaction { get; }

public TransactionEventArgs(Transaction transaction)
{
Transaction = transaction;
}
}
}
108 changes: 108 additions & 0 deletions BitNav/TransactionManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using NBitcoin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace BitNav
{
public class TransactionManager
{
private List<Transaction> transactions;
private List<Transaction> unconfirmedTransactions;
private List<Transaction> confirmedTransactions;

private Thread transactionChecker;

public TransactionManager()
{
transactions = new List<Transaction>();
unconfirmedTransactions = new List<Transaction>();
confirmedTransactions = new List<Transaction>();
transactionChecker = transactionCheckerThread();
transactionChecker.Start();
}


private Thread transactionCheckerThread()
{
Thread t = new Thread(() => checkTransactions());
return t;
}

private void checkTransactions()
{
while (true)
{
List<Transaction> transactionsToRemove = new List<Transaction>();

lock (unconfirmedTransactions)
{
lock (confirmedTransactions)
{
foreach (Transaction transaction in unconfirmedTransactions)
{
if (transaction.checkTransactionConfirmed())
{
confirmedTransactions.Add(transaction);
transactionsToRemove.Add(transaction);

}
}

foreach (Transaction transaction in transactionsToRemove)
{
unconfirmedTransactions.Remove(transaction);
}
}
}

Thread.Sleep(120000);
}

}
//create Transaction
public Transaction CreateTransaction(object coin, int amount, string address)
{
Transaction transaction = new Transaction(coin, amount, address);
transactions.Add(transaction);
lock (unconfirmedTransactions)
{
unconfirmedTransactions.Add(transaction);
}
return transaction;
}
//add transaction
public void AddTransaction(Transaction transaction)
{
transactions.Add(transaction);
lock (unconfirmedTransactions)
{
unconfirmedTransactions.Add(transaction);
}
}

//remove transaction
public void RemoveTransaction(Transaction transaction)
{
transactions.Remove(transaction);

lock (unconfirmedTransactions)
{
unconfirmedTransactions.Remove(transaction);
}

lock (confirmedTransactions)
{
confirmedTransactions.Remove(transaction);
}
}

public List<Transaction> GetTransactions()
{
return transactions;
}
}
}
Binary file modified BitNav/bin/Debug/net6.0/BitNav.dll
Binary file not shown.
Binary file modified BitNav/bin/Debug/net6.0/BitNav.pdb
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
542994ee8e765cc01a5c59c10ed55d6e30822ae6
84854501d6e1b19c142c1994e6a0828119e7f823
Binary file modified BitNav/obj/Debug/net6.0/BitNav.dll
Binary file not shown.
Binary file modified BitNav/obj/Debug/net6.0/BitNav.pdb
Binary file not shown.
Binary file modified BitNav/obj/Debug/net6.0/ref/BitNav.dll
Binary file not shown.
Binary file modified BitNav/obj/Debug/net6.0/refint/BitNav.dll
Binary file not shown.