diff --git a/.gitignore b/.gitignore
index 5bf053a..446cab1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -101,6 +101,8 @@ ENV/
# mypy
.mypy_cache/
+# Distribution / packaging VSCode
.vscode/
C++/analyseValgrind.sh
C++/analyseValgrind.txt
+C#/obj
\ No newline at end of file
diff --git a/C#/App.config b/C#/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/C#/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/C#/BismuthAPI.cs b/C#/BismuthAPI.cs
new file mode 100644
index 0000000..afb809c
--- /dev/null
+++ b/C#/BismuthAPI.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Linq;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.IO;
+using System.Text;
+
+public class BismuthAPI
+{
+ private string server;
+ private int port;
+ private TcpClient tcpClientAPI = null;
+ private NetworkStream tcpStream;
+
+ public BismuthAPI(string nodeServer, int nodePort)
+ {
+ this.server = nodeServer;
+ this.port = nodePort;
+ this.cnxCheck();
+ }
+
+ ~BismuthAPI()
+ {
+ tcpStream.Close();
+ tcpClientAPI.Close();
+ }
+
+ public string Command(params object[] cmds)
+ {
+ for (int i = 0; i < cmds.Length; i++) this.Send(cmds[i]);
+ return this.Receive();
+ }
+
+ public string Receive()
+ {
+ Byte[] lengthSocketMessage = new Byte[10];
+ String responseData = String.Empty;
+
+ Int32 nBytes = tcpStream.Read(lengthSocketMessage, 0, lengthSocketMessage.Length);
+ responseData = System.Text.Encoding.ASCII.GetString(lengthSocketMessage, 0, nBytes);
+ Int32 socketLenReceiveMessage = Int32.Parse(responseData);
+ int socketTotalReceiveBytes = 0;
+
+ string strJson;
+ using (MemoryStream ms = new MemoryStream())
+ {
+ Byte[] data = new Byte[socketLenReceiveMessage];
+
+ int numBytesRead;
+ while ((numBytesRead = tcpStream.Read(data, 0, data.Length)) > 0)
+ {
+ Console.WriteLine("numBytesRead: "+ numBytesRead);
+ ms.Write(data, 0, numBytesRead);
+ socketTotalReceiveBytes += numBytesRead;
+ if (socketTotalReceiveBytes == socketLenReceiveMessage) break;
+ }
+ strJson = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
+ }
+
+ return strJson;
+ }
+
+ public void Send(object cmd)
+ {
+ Byte[] data;
+
+ string socketMessage = JsonConvert.SerializeObject(cmd);
+ socketMessage = string.Format("{0:D10}", socketMessage.Length) + socketMessage;
+ data = System.Text.Encoding.ASCII.GetBytes(socketMessage);
+ tcpStream.Write(data, 0, data.Length);
+ }
+
+ static public string JsonDump(string jsonData)
+ {
+ JToken jt = JToken.Parse(jsonData);
+ return jt.ToString();
+ }
+
+ private void cnxCheck()
+ {
+ if (this.tcpClientAPI == null)
+ {
+ try
+ {
+ this.tcpClientAPI = new TcpClient(this.server, this.port);
+ this.tcpStream = this.tcpClientAPI.GetStream();
+ }
+ catch (SocketException e)
+ {
+ Console.WriteLine("SocketException: {0}", e);
+ }
+ }
+ }
+
+ private TcpState getTCPState()
+ {
+ var foo = IPGlobalProperties.GetIPGlobalProperties()
+ .GetActiveTcpConnections()
+ .SingleOrDefault(x => x.LocalEndPoint.Equals(this.tcpClientAPI.Client.LocalEndPoint)
+ && x.RemoteEndPoint.Equals(this.tcpClientAPI.Client.RemoteEndPoint)
+ );
+
+ return foo != null ? foo.State : TcpState.Unknown;
+ }
+}
diff --git a/C#/BismuthAPI.csproj b/C#/BismuthAPI.csproj
new file mode 100644
index 0000000..6a21428
--- /dev/null
+++ b/C#/BismuthAPI.csproj
@@ -0,0 +1,70 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B49F850E-3516-451F-9B26-550E24C9FB0B}
+ Exe
+ Properties
+ BismuthAPI
+ BismuthAPI
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ Demo_getaddress_since
+
+
+
+ packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/C#/BismuthAPI.sln b/C#/BismuthAPI.sln
new file mode 100644
index 0000000..bf6bed9
--- /dev/null
+++ b/C#/BismuthAPI.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BismuthAPI", "BismuthAPI.csproj", "{B49F850E-3516-451F-9B26-550E24C9FB0B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B49F850E-3516-451F-9B26-550E24C9FB0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B49F850E-3516-451F-9B26-550E24C9FB0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B49F850E-3516-451F-9B26-550E24C9FB0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B49F850E-3516-451F-9B26-550E24C9FB0B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/C#/Demo.cs b/C#/Demo.cs
new file mode 100644
index 0000000..ceea6aa
--- /dev/null
+++ b/C#/Demo.cs
@@ -0,0 +1,54 @@
+using System;
+
+class Demo
+ {
+ static void Main(string[] args)
+ {
+ string ret = String.Empty;
+
+ BismuthAPI connectionBismuthAPI = new BismuthAPI("127.0.0.1", 5658);
+
+ // Ask for general status
+ Console.WriteLine("statusjson:");
+ ret = connectionBismuthAPI.Command("statusjson");
+ Console.WriteLine(ret);
+ Console.WriteLine();
+
+ // Gets a specific block details
+ Console.WriteLine("blockget(558742):");
+ ret = connectionBismuthAPI.Command("blockget", 558742);
+ Console.WriteLine(ret);
+ Console.WriteLine();
+
+ // Gets latest block and diff
+ Console.WriteLine("difflast:");
+ ret = connectionBismuthAPI.Command("difflast");
+ Console.WriteLine(ret);
+ Console.WriteLine();
+
+ // Gets tx detail, raw format
+ Console.WriteLine("api_gettransaction('K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj', false):");
+ ret = connectionBismuthAPI.Command("api_gettransaction", "K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj", false);
+ Console.WriteLine(ret);
+ Console.WriteLine();
+
+ // Gets tx detail, json format
+ Console.WriteLine("api_gettransaction('K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj', true):");
+ ret = connectionBismuthAPI.Command("api_gettransaction", "K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj", true);
+ Console.WriteLine(ret);
+ Console.WriteLine();
+
+ // Gets addresses balances
+ Console.WriteLine("api_listbalance(['731337bb0f76463d578626a48367dfea4c6efcfa317604814f875d10','340c195f768be515488a6efedb958e135150b2ef3e53573a7017ac7d'], 0, true):");
+ string[] addresses = new string[] { "731337bb0f76463d578626a48367dfea4c6efcfa317604814f875d10", "340c195f768be515488a6efedb958e135150b2ef3e53573a7017ac7d" };
+ ret = connectionBismuthAPI.Command("api_listbalance", addresses, 0, true);
+ Console.WriteLine(ret);
+ Console.WriteLine();
+
+ // Ask for a new keys/address set
+ Console.WriteLine("keygen:");
+ ret = connectionBismuthAPI.Command("keygen");
+ Console.WriteLine(ret);
+ Console.WriteLine();
+ }
+}
diff --git a/C#/Demo_getaddress_since.cs b/C#/Demo_getaddress_since.cs
new file mode 100644
index 0000000..cba5e7a
--- /dev/null
+++ b/C#/Demo_getaddress_since.cs
@@ -0,0 +1,46 @@
+using System;
+
+class Demo_getaddress_since
+{
+ static string Get_address_since(int since, int min_conf, string address)
+ {
+ BismuthAPI connectionBismuthAPI = new BismuthAPI("127.0.0.1", 5658);
+
+ // Command first
+ connectionBismuthAPI.Send("api_getaddresssince");
+ // Then last block
+ connectionBismuthAPI.Send(since);
+ // min confirmations
+ connectionBismuthAPI.Send(min_conf);
+ // and finally the address
+ connectionBismuthAPI.Send(address);
+
+ return connectionBismuthAPI.Receive();
+ }
+
+ static void Usage(string message)
+ {
+ Console.WriteLine(message);
+ Console.WriteLine("Usage: BismuthAPI ");
+ Environment.Exit(1);
+ }
+
+ static void Main(string[] args)
+ {
+ string res_as_native_dict = String.Empty;
+ int since, min_conf;
+ string address;
+
+ if (args.Length != 3) Usage("Please enter arguments.");
+ if (int.TryParse(args[0], out since) == false) Usage("Please enter a numeric argument for last known block: ");
+ if (int.TryParse(args[1], out min_conf) == false) Usage("Please enter a numeric argument for min confirmations: ");
+ address = args[2];
+
+ Console.WriteLine("api_getaddresssince since " + since + " minconf=" + min_conf + " for address " + address);
+ res_as_native_dict = Get_address_since(since, min_conf, address);
+ Console.WriteLine(BismuthAPI.JsonDump(res_as_native_dict));
+ Console.WriteLine();
+
+ Environment.Exit(0);
+ }
+}
\ No newline at end of file
diff --git a/C#/Properties/AssemblyInfo.cs b/C#/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6aa87f8
--- /dev/null
+++ b/C#/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BismuthAPI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BismuthAPI")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b49f850e-3516-451f-9b26-550e24c9fb0b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/C#/README.md b/C#/README.md
new file mode 100644
index 0000000..17a4285
--- /dev/null
+++ b/C#/README.md
@@ -0,0 +1,31 @@
+# C# code for Bismuth Native API access
+
+Demonstrates the use of a simple C# client library.
+
++ [BismuthAPI.cs](BismuthAPI.cs) : C# Client library
++ [Demo.cs](Demo.cs) : A simple demo app, showing a few simple commands. It's needs a running node.
++ [Demo_getaddress_since.cs](Demo_getaddress_since.cs) : A simple demo app, showing the `api_getaddresssince` api command. It's needs a running node.
+
+## Notes
+
+Use [newtonsoft-json](https://www.nuget.org/packages/Newtonsoft.Json/) package to parse JSON API response. To download from NuGet, You can do this a couple of ways.
+
+**Via the "Solution Explorer"**
+
+ Simply right-click the "References" folder and select "Manage NuGet Packages..."
+ Once that window comes up click on the option labeled "Online" in the left most part of the dialog.
+ Then in the search bar in the upper right type "json.net"
+ Click "Install" and you're done.
+
+**Via the "Package Manager Console"**
+
+ Open the console. "View" > "Other Windows" > "Package Manager Console"
+ Then type the following:
+
+ Install-Package Newtonsoft.Json
+
+For more info on how to use the "Package Manager Console" check out the [nuget docs](https://docs.microsoft.com/fr-fr/nuget/tools/package-manager-console).
+
+### Patches
+
+Anybody can contribute to development. If you are contributing a source code change, use a merge request of a Git branch.
\ No newline at end of file
diff --git a/C#/packages.config b/C#/packages.config
new file mode 100644
index 0000000..07e3593
--- /dev/null
+++ b/C#/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file