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(); } [JsonProperty(PropertyName = "method", Order = 0)] public string Method { get; set; } [JsonProperty(PropertyName = "params", Order = 1)] public IList 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 { /// /// Returns a string value for the property provided from the JSON string this extension method is applied to. /// /// The JSON property name path whos value we want returned. Example: from getblock result select "result.weight" /// public static string GetProperty(this String str, string property) { var jObject = JObject.Parse(str); string result = (string)jObject.SelectToken(property); return result; } /// /// Returns an IList of strings from the array of JSON data located at the 'path' specified. /// /// 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" /// An IList of strings public static IList GetStringList(this String str, string path) { var jObject = JObject.Parse(str); IList items = jObject.SelectToken("$." + path).Select(s => (string)s).ToList(); return items; } /// /// Returns an IList of objects from the array of JSON data located at the 'path' specified. /// /// 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" /// An IList of objects public static IList GetObjectList(this String str, string path) { var jObject = JObject.Parse(str); IList items = jObject.SelectToken("$." + path).Select(s => (object)s).ToList(); return items; } /// /// Returns a Dictionary of key/value pairs from the JSON data located at the 'path' specified. /// /// 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" /// A string,object key/value Dictionary public static Dictionary GetKeyValuePairs(this String str, string path) { var jObject = JObject.Parse(str); var jTokens = jObject.SelectToken("$." + path); var kvPairs = jTokens.ToObject>(); return kvPairs; } } }