/
dotnetcoreDynamicJSON-RPC.cs
183 lines (159 loc) · 7.09 KB
/
dotnetcoreDynamicJSON-RPC.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
// The latest version of this code can be found here:
// https://github.com/wintercooled/dotnetcoreDynamicJSON-RPC
namespace DotnetcoreDynamicJSONRPC
{
class DynamicRPC : DynamicObject
{
private string rpcUrl;
private string rpcPort;
private string rpcUser;
private string rpcPassword;
public DynamicRPC(string rpcUrl, string rpcPort, string rpcUser, string rpcPassword)
{
this.rpcUrl = rpcUrl;
this.rpcPort = rpcPort;
this.rpcUser = rpcUser;
this.rpcPassword = rpcPassword;
}
public bool DaemonIsRunning(string parameterlessTestCommand = "getblockcount")
{
try
{
string check = SendRPC(parameterlessTestCommand, null);
return true;
}
catch { return false; }
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
Type type = typeof(DynamicRPC);
try {
result = type.InvokeMember(
"SendRPC",
BindingFlags.InvokeMethod,
null,
this,
new object[] { binder.Name, args }
);
return true;
}
catch (Exception) {
throw new Exception("An error occured executing the RPC command \"" + binder.Name + "\"." +
"Check the daemon is running with the same RPC credentials passed into dotnetcoreDynamicJSON_RPC and that the command and parameters are correctly formed.");
}
}
public string SendRPC(string method, object[] args)
{
string jsonResponse;
//Console.WriteLine(method);
JsonRPCRequest jsonRpcRequest = new JsonRPCRequest(method, args);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(this.rpcUrl + ":" + this.rpcPort);
// The following was used when testing on Windows. Needs checking as it is likely redundant
// due to other code changes here. Removing for now.
//SetAuthorizationHeader(webRequest, this.rpcUser, this.rpcPassword);
webRequest.Credentials = new NetworkCredential(this.rpcUser, this.rpcPassword);
webRequest.ContentType = "application/json-rpc";
webRequest.Method = "POST";
byte[] requestBytes = jsonRpcRequest.GetBytes();
webRequest.ContentLength = jsonRpcRequest.GetBytes().Length;
using (Stream requestStream = webRequest.GetRequestStream())
{
requestStream.Write(requestBytes, 0, requestBytes.Length);
requestStream.Close();
}
using (WebResponse webResponse = webRequest.GetResponse())
using (Stream responseStream = webResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
jsonResponse = reader.ReadToEnd();
reader.Close();
}
return jsonResponse;
}
public class JsonRPCRequest
{
public JsonRPCRequest(string method, object[] args)
{
Method = method;
Parameters = args?.ToList() ?? new List<object>();
}
[JsonProperty(PropertyName = "method", Order = 0)]
public string Method { get; set; }
[JsonProperty(PropertyName = "params", Order = 1)]
public IList<object> Parameters { get; set; }
public string GetString()
{
return JsonConvert.SerializeObject(this);
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(GetString());
}
}
private static void SetAuthorizationHeader(WebRequest webRequest, string user, string password)
{
string credentials = user + ":" + password;
credentials = Convert.ToBase64String(Encoding.Default.GetBytes(credentials));
webRequest.Headers["Authorization"] = "Basic" + " " + credentials;
}
}
public static class RPCResultExtensions
{
/// <summary>
/// Returns a string value for the property provided from the JSON string this extension method is applied to.
/// </summary>
/// <param name="property">The JSON property name path whos value we want returned. Example: from getblock result select "result.weight"</param>
/// <returns></returns>
public static string GetProperty(this String str, string property)
{
var jObject = JObject.Parse(str);
string result = (string)jObject.SelectToken(property);
return result;
}
/// <summary>
/// Returns an IList of strings from the array of JSON data located at the 'path' specified.
/// </summary>
/// <param name="path">The path to the array of objects you want returned from the JSON string this extension method is used on. Example: from getblock result select "result.tx"</param>
/// <returns>An IList of strings</returns>
public static IList<string> GetStringList(this String str, string path)
{
var jObject = JObject.Parse(str);
IList<string> items = jObject.SelectToken("$." + path).Select(s => (string)s).ToList();
return items;
}
/// <summary>
/// Returns an IList of objects from the array of JSON data located at the 'path' specified.
/// </summary>
/// <param name="path">The path to the array of objects you want returned from the JSON string this extension method is used on. Example: from decoderawtransaction result select "result.vout"</param>
/// <returns>An IList of objects</returns>
public static IList<object> GetObjectList(this String str, string path)
{
var jObject = JObject.Parse(str);
IList<object> items = jObject.SelectToken("$." + path).Select(s => (object)s).ToList();
return items;
}
/// <summary>
/// Returns a Dictionary of key/value pairs from the JSON data located at the 'path' specified.
/// </summary>
/// <param name="path">The path to the key/value pairs you want returned from the JSON string this extension method is used on. Example: from getwalletinfo result select "result"</param>
/// <returns>A string,object key/value Dictionary</returns>
public static Dictionary<string, object> GetKeyValuePairs(this String str, string path)
{
var jObject = JObject.Parse(str);
var jTokens = jObject.SelectToken("$." + path);
var kvPairs = jTokens.ToObject<Dictionary<string, object>>();
return kvPairs;
}
}
}