Skip to content

Commit 31ba6bf

Browse files
authored
Merge pull request #7 from LeMoussel/master
C# library for accessing the Bismuth Native API access.
2 parents f440aed + e9c3736 commit 31ba6bf

File tree

10 files changed

+378
-0
lines changed

10 files changed

+378
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ ENV/
101101
# mypy
102102
.mypy_cache/
103103

104+
# Distribution / packaging VSCode
104105
.vscode/
105106
C++/analyseValgrind.sh
106107
C++/analyseValgrind.txt
108+
C#/obj

C#/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
5+
</startup>
6+
</configuration>

C#/BismuthAPI.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System;
2+
using System.Linq;
3+
using System.Net.Sockets;
4+
using System.Net.NetworkInformation;
5+
using Newtonsoft.Json;
6+
using Newtonsoft.Json.Linq;
7+
using System.IO;
8+
using System.Text;
9+
10+
public class BismuthAPI
11+
{
12+
private string server;
13+
private int port;
14+
private TcpClient tcpClientAPI = null;
15+
private NetworkStream tcpStream;
16+
17+
public BismuthAPI(string nodeServer, int nodePort)
18+
{
19+
this.server = nodeServer;
20+
this.port = nodePort;
21+
this.cnxCheck();
22+
}
23+
24+
~BismuthAPI()
25+
{
26+
tcpStream.Close();
27+
tcpClientAPI.Close();
28+
}
29+
30+
public string Command(params object[] cmds)
31+
{
32+
for (int i = 0; i < cmds.Length; i++) this.Send(cmds[i]);
33+
return this.Receive();
34+
}
35+
36+
public string Receive()
37+
{
38+
Byte[] lengthSocketMessage = new Byte[10];
39+
String responseData = String.Empty;
40+
41+
Int32 nBytes = tcpStream.Read(lengthSocketMessage, 0, lengthSocketMessage.Length);
42+
responseData = System.Text.Encoding.ASCII.GetString(lengthSocketMessage, 0, nBytes);
43+
Int32 socketLenReceiveMessage = Int32.Parse(responseData);
44+
int socketTotalReceiveBytes = 0;
45+
46+
string strJson;
47+
using (MemoryStream ms = new MemoryStream())
48+
{
49+
Byte[] data = new Byte[socketLenReceiveMessage];
50+
51+
int numBytesRead;
52+
while ((numBytesRead = tcpStream.Read(data, 0, data.Length)) > 0)
53+
{
54+
Console.WriteLine("numBytesRead: "+ numBytesRead);
55+
ms.Write(data, 0, numBytesRead);
56+
socketTotalReceiveBytes += numBytesRead;
57+
if (socketTotalReceiveBytes == socketLenReceiveMessage) break;
58+
}
59+
strJson = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
60+
}
61+
62+
return strJson;
63+
}
64+
65+
public void Send(object cmd)
66+
{
67+
Byte[] data;
68+
69+
string socketMessage = JsonConvert.SerializeObject(cmd);
70+
socketMessage = string.Format("{0:D10}", socketMessage.Length) + socketMessage;
71+
data = System.Text.Encoding.ASCII.GetBytes(socketMessage);
72+
tcpStream.Write(data, 0, data.Length);
73+
}
74+
75+
static public string JsonDump(string jsonData)
76+
{
77+
JToken jt = JToken.Parse(jsonData);
78+
return jt.ToString();
79+
}
80+
81+
private void cnxCheck()
82+
{
83+
if (this.tcpClientAPI == null)
84+
{
85+
try
86+
{
87+
this.tcpClientAPI = new TcpClient(this.server, this.port);
88+
this.tcpStream = this.tcpClientAPI.GetStream();
89+
}
90+
catch (SocketException e)
91+
{
92+
Console.WriteLine("SocketException: {0}", e);
93+
}
94+
}
95+
}
96+
97+
private TcpState getTCPState()
98+
{
99+
var foo = IPGlobalProperties.GetIPGlobalProperties()
100+
.GetActiveTcpConnections()
101+
.SingleOrDefault(x => x.LocalEndPoint.Equals(this.tcpClientAPI.Client.LocalEndPoint)
102+
&& x.RemoteEndPoint.Equals(this.tcpClientAPI.Client.RemoteEndPoint)
103+
);
104+
105+
return foo != null ? foo.State : TcpState.Unknown;
106+
}
107+
}

C#/BismuthAPI.csproj

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{B49F850E-3516-451F-9B26-550E24C9FB0B}</ProjectGuid>
8+
<OutputType>Exe</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>BismuthAPI</RootNamespace>
11+
<AssemblyName>BismuthAPI</AssemblyName>
12+
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<PlatformTarget>AnyCPU</PlatformTarget>
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<PlatformTarget>AnyCPU</PlatformTarget>
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>bin\Release\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<PropertyGroup>
36+
<StartupObject>Demo_getaddress_since</StartupObject>
37+
</PropertyGroup>
38+
<ItemGroup>
39+
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
40+
<HintPath>packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
41+
<Private>True</Private>
42+
</Reference>
43+
<Reference Include="System" />
44+
<Reference Include="System.Core" />
45+
<Reference Include="System.Xml.Linq" />
46+
<Reference Include="System.Data.DataSetExtensions" />
47+
<Reference Include="Microsoft.CSharp" />
48+
<Reference Include="System.Data" />
49+
<Reference Include="System.Net.Http" />
50+
<Reference Include="System.Xml" />
51+
</ItemGroup>
52+
<ItemGroup>
53+
<Compile Include="BismuthAPI.cs" />
54+
<Compile Include="Demo.cs" />
55+
<Compile Include="Demo_getaddress_since.cs" />
56+
<Compile Include="Properties\AssemblyInfo.cs" />
57+
</ItemGroup>
58+
<ItemGroup>
59+
<None Include="App.config" />
60+
<None Include="packages.config" />
61+
</ItemGroup>
62+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
63+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
64+
Other similar extension points exist, see Microsoft.Common.targets.
65+
<Target Name="BeforeBuild">
66+
</Target>
67+
<Target Name="AfterBuild">
68+
</Target>
69+
-->
70+
</Project>

C#/BismuthAPI.sln

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25420.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BismuthAPI", "BismuthAPI.csproj", "{B49F850E-3516-451F-9B26-550E24C9FB0B}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{B49F850E-3516-451F-9B26-550E24C9FB0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{B49F850E-3516-451F-9B26-550E24C9FB0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{B49F850E-3516-451F-9B26-550E24C9FB0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{B49F850E-3516-451F-9B26-550E24C9FB0B}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal

C#/Demo.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
3+
class Demo
4+
{
5+
static void Main(string[] args)
6+
{
7+
string ret = String.Empty;
8+
9+
BismuthAPI connectionBismuthAPI = new BismuthAPI("127.0.0.1", 5658);
10+
11+
// Ask for general status
12+
Console.WriteLine("statusjson:");
13+
ret = connectionBismuthAPI.Command("statusjson");
14+
Console.WriteLine(ret);
15+
Console.WriteLine();
16+
17+
// Gets a specific block details
18+
Console.WriteLine("blockget(558742):");
19+
ret = connectionBismuthAPI.Command("blockget", 558742);
20+
Console.WriteLine(ret);
21+
Console.WriteLine();
22+
23+
// Gets latest block and diff
24+
Console.WriteLine("difflast:");
25+
ret = connectionBismuthAPI.Command("difflast");
26+
Console.WriteLine(ret);
27+
Console.WriteLine();
28+
29+
// Gets tx detail, raw format
30+
Console.WriteLine("api_gettransaction('K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj', false):");
31+
ret = connectionBismuthAPI.Command("api_gettransaction", "K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj", false);
32+
Console.WriteLine(ret);
33+
Console.WriteLine();
34+
35+
// Gets tx detail, json format
36+
Console.WriteLine("api_gettransaction('K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj', true):");
37+
ret = connectionBismuthAPI.Command("api_gettransaction", "K1iuKwkOac4HSuzEBDxmqb5dOmfXEK98BaWQFHltdrbDd0C5iIEbh/Fj", true);
38+
Console.WriteLine(ret);
39+
Console.WriteLine();
40+
41+
// Gets addresses balances
42+
Console.WriteLine("api_listbalance(['731337bb0f76463d578626a48367dfea4c6efcfa317604814f875d10','340c195f768be515488a6efedb958e135150b2ef3e53573a7017ac7d'], 0, true):");
43+
string[] addresses = new string[] { "731337bb0f76463d578626a48367dfea4c6efcfa317604814f875d10", "340c195f768be515488a6efedb958e135150b2ef3e53573a7017ac7d" };
44+
ret = connectionBismuthAPI.Command("api_listbalance", addresses, 0, true);
45+
Console.WriteLine(ret);
46+
Console.WriteLine();
47+
48+
// Ask for a new keys/address set
49+
Console.WriteLine("keygen:");
50+
ret = connectionBismuthAPI.Command("keygen");
51+
Console.WriteLine(ret);
52+
Console.WriteLine();
53+
}
54+
}

C#/Demo_getaddress_since.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
3+
class Demo_getaddress_since
4+
{
5+
static string Get_address_since(int since, int min_conf, string address)
6+
{
7+
BismuthAPI connectionBismuthAPI = new BismuthAPI("127.0.0.1", 5658);
8+
9+
// Command first
10+
connectionBismuthAPI.Send("api_getaddresssince");
11+
// Then last block
12+
connectionBismuthAPI.Send(since);
13+
// min confirmations
14+
connectionBismuthAPI.Send(min_conf);
15+
// and finally the address
16+
connectionBismuthAPI.Send(address);
17+
18+
return connectionBismuthAPI.Receive();
19+
}
20+
21+
static void Usage(string message)
22+
{
23+
Console.WriteLine(message);
24+
Console.WriteLine("Usage: BismuthAPI <block_height> <min_conf> <address>");
25+
Environment.Exit(1);
26+
}
27+
28+
static void Main(string[] args)
29+
{
30+
string res_as_native_dict = String.Empty;
31+
int since, min_conf;
32+
string address;
33+
34+
if (args.Length != 3) Usage("Please enter arguments.");
35+
if (int.TryParse(args[0], out since) == false) Usage("Please enter a numeric argument for last known block: <block_height>");
36+
if (int.TryParse(args[1], out min_conf) == false) Usage("Please enter a numeric argument for min confirmations: <min_conf >");
37+
address = args[2];
38+
39+
Console.WriteLine("api_getaddresssince since " + since + " minconf=" + min_conf + " for address " + address);
40+
res_as_native_dict = Get_address_since(since, min_conf, address);
41+
Console.WriteLine(BismuthAPI.JsonDump(res_as_native_dict));
42+
Console.WriteLine();
43+
44+
Environment.Exit(0);
45+
}
46+
}

C#/Properties/AssemblyInfo.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("BismuthAPI")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("BismuthAPI")]
13+
[assembly: AssemblyCopyright("Copyright © 2018")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("b49f850e-3516-451f-9b26-550e24c9fb0b")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]

C#/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# C# code for Bismuth Native API access
2+
3+
Demonstrates the use of a simple C# client library.
4+
5+
+ [BismuthAPI.cs](BismuthAPI.cs) : C# Client library
6+
+ [Demo.cs](Demo.cs) : A simple demo app, showing a few simple commands. It's needs a running node.
7+
+ [Demo_getaddress_since.cs](Demo_getaddress_since.cs) : A simple demo app, showing the `api_getaddresssince` api command. It's needs a running node.
8+
9+
## Notes
10+
11+
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.
12+
13+
**Via the "Solution Explorer"**
14+
15+
Simply right-click the "References" folder and select "Manage NuGet Packages..."
16+
Once that window comes up click on the option labeled "Online" in the left most part of the dialog.
17+
Then in the search bar in the upper right type "json.net"
18+
Click "Install" and you're done.
19+
20+
**Via the "Package Manager Console"**
21+
22+
Open the console. "View" > "Other Windows" > "Package Manager Console"
23+
Then type the following:
24+
25+
Install-Package Newtonsoft.Json
26+
27+
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).
28+
29+
### Patches
30+
31+
Anybody can contribute to development. If you are contributing a source code change, use a merge request of a Git branch.

C#/packages.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net452" />
4+
</packages>

0 commit comments

Comments
 (0)