diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eba7dde
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,191 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+x64/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+#NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding addin-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+_NCrunch_*
+.*crunch*.local.xml
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+
+# NuGet Packages Directory
+packages/
+*.nupkg
+NBitcoin.Mono.nuspec
+NBitcoin.nuspec
+
+## TODO: If the tool you use requires repositories.config uncomment the next line
+#!packages/repositories.config
+
+# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
+# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
+!packages/build/
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+/.vs/config/applicationhost.config
+/NBitcoin.Portable/NBitcoin(MonoAndroid).csproj.bak
+/NBitcoin.Portable/NBitcoin(Mono).csproj.bak
+
+# .NET Core projects
+.vs/
+project.lock.json
+.vscode/
+/NBitcoin.Tests/CanStoreInBlockRepository-Headers/StoreLock
+/NBitcoin.Tests/addrmancache.dat
+/NBitcoin.Tests/CanStoreBlocks/StoreLock
+/NBitcoin.Tests/libbitcoinconsensus-0.dll
+*.zip
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2d217b2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Sphere 10 Software
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/NPascalCoin.sln b/NPascalCoin.sln
new file mode 100644
index 0000000..47b5694
--- /dev/null
+++ b/NPascalCoin.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}") = "NPascalCoin", "NPascalCoin\NPascalCoin.csproj", "{527FBE08-46AF-49C9-9479-FEFF1FA9EBF8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {527FBE08-46AF-49C9-9479-FEFF1FA9EBF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {527FBE08-46AF-49C9-9479-FEFF1FA9EBF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {527FBE08-46AF-49C9-9479-FEFF1FA9EBF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {527FBE08-46AF-49C9-9479-FEFF1FA9EBF8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/NPascalCoin/Constants.cs b/NPascalCoin/Constants.cs
new file mode 100644
index 0000000..51cf322
--- /dev/null
+++ b/NPascalCoin/Constants.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NPascalCoin {
+ internal static class Constants {
+ public const string NPascalCoinVersion = "0.1";
+ }
+}
diff --git a/NPascalCoin/DTO/AccountDTO.cs b/NPascalCoin/DTO/AccountDTO.cs
new file mode 100644
index 0000000..c5e6add
--- /dev/null
+++ b/NPascalCoin/DTO/AccountDTO.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// An "Account object" is a JSON object with information about an account.
+ ///
+ public class AccountDTO {
+
+ ///
+ /// Account number
+ ///
+ [JsonProperty("account")]
+ public uint Account { get; set; }
+
+ ///
+ /// Encoded public key value (hexastring)
+ ///
+ [JsonProperty("enc_pubkey")]
+ public string EncPubKey { get; set; }
+
+ ///
+ /// Account balance (PASCURRENCY)
+ ///
+ [JsonProperty("balance")]
+ public decimal Balance { get; set; }
+
+ ///
+ /// Operations made by this account (Note: When an account receives a transaction, n_operation is not changed)
+ ///
+ [JsonProperty("n_operation")]
+ public uint NumOperations { get; set; }
+
+ ///
+ /// Last block that updated this account. If equal to blockchain blocks count it means that it has pending operations to be included to the blockchain
+ ///
+ [JsonProperty("updated_b")]
+ public uint LastUpdatedBlock { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/DTO/BlockDTO.cs b/NPascalCoin/DTO/BlockDTO.cs
new file mode 100644
index 0000000..55058b6
--- /dev/null
+++ b/NPascalCoin/DTO/BlockDTO.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// A "Block object" is a JSON object with information about a Blockchain's block.
+ ///
+ public class BlockDTO {
+
+ ///
+ /// Block number
+ ///
+ [JsonProperty("block")]
+ public uint Block { get; set; }
+
+ ///
+ /// Last block that updated this account. If equal to blockchain blocks count it means that it has pending operations to be included to the blockchain
+ ///
+ [JsonProperty("enc_pubkey")]
+ public string EncPubKey { get; set; }
+
+ ///
+ /// Reward of first account's block
+ ///
+ [JsonProperty("reward")]
+ public decimal Reward { get; set; }
+
+ ///
+ /// Fee obtained by operations (PASCURRENCY)
+ ///
+ [JsonProperty("fee")]
+ public decimal Fee { get; set; }
+
+ ///
+ /// Pascal Coin protocol used
+ ///
+ [JsonProperty("ver")]
+ public uint Version { get; set; }
+
+ ///
+ /// Pascal Coin protocol available by the miner
+ ///
+ [JsonProperty("ver_a")]
+ public uint AvailableVersion { get; set; }
+
+ ///
+ /// Unix timestamp
+ ///
+ [JsonProperty("timestamp")]
+ public uint Timestamp { get; set; }
+
+ ///
+ /// Target used
+ ///
+ [JsonProperty("target")]
+ public uint CompactTarget { get; set; }
+
+ ///
+ /// Nonce used
+ ///
+ [JsonProperty("nonce")]
+ public uint Nonce { get; set; }
+
+ ///
+ /// Miner's payload
+ ///
+ [JsonProperty("payload")]
+ public string Payload { get; set; }
+
+ ///
+ /// SafeBox Hash
+ ///
+ [JsonProperty("sbh")]
+ public string SafeBoxHash { get; set; }
+
+ ///
+ /// Operations hash
+ ///
+ [JsonProperty("oph")]
+ public string OperationsHash { get; set; }
+
+ ///
+ /// Proof of work
+ ///
+ [JsonProperty("pow")]
+ public string ProofOfWork { get; set; }
+
+ ///
+ /// Number of operations included in this block
+ ///
+ [JsonProperty("operations")]
+ public uint OperationCount { get; set; }
+
+ ///
+ /// Estimated network hashrate calculated by previous 50 blocks average
+ ///
+ [JsonProperty("hashratekhs")]
+ public uint Last50HashRateKhs { get; set; }
+
+ ///
+ /// Number of blocks in the blockchain higher than this
+ ///
+ [JsonProperty("maturation")]
+ public uint Maturation { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/DTO/ConnectionDTO.cs b/NPascalCoin/DTO/ConnectionDTO.cs
new file mode 100644
index 0000000..d04e30e
--- /dev/null
+++ b/NPascalCoin/DTO/ConnectionDTO.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// A "Connection object" is a JSON object with a connection to other node information.
+ ///
+ public class ConnectionDTO {
+
+ ///
+ /// True if this connection is to a server node.False if this connection is a client node
+ ///
+ [JsonProperty("server")]
+ public bool IsServer { get; set; }
+
+ ///
+ /// IP
+ ///
+ [JsonProperty("ip")]
+ public string IP { get; set; }
+
+ ///
+ /// Port
+ ///
+ [JsonProperty("port")]
+ public int Port { get; set; }
+
+ ///
+ /// seconds of live of this connection
+ ///
+ [JsonProperty("secs")]
+ public uint ConnectedDurationSec { get; set; }
+
+ ///
+ /// Bytes sent
+ ///
+ [JsonProperty("sent")]
+ public uint BytesSent { get; set; }
+
+ ///
+ /// Bytes received
+ ///
+ [JsonProperty("recv")]
+ public int BytesReceived { get; set; }
+
+ ///
+ /// Other node App version
+ ///
+ [JsonProperty("appver")]
+ public string AppVersion { get; set; }
+
+ ///
+ /// Net protocol of other node
+ ///
+ [JsonProperty("netvar")]
+ public uint RemoteVersion { get; set; }
+
+ ///
+ /// Net protocol available of other node
+ ///
+ [JsonProperty("netvar_a")]
+ public uint RemoveAvailableVersion { get; set; }
+
+ ///
+ /// Net timediff of other node (vs wallet)
+ ///
+ [JsonProperty("timediff")]
+ public uint TimeDiff { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/DTO/DecryptedPayloadDTO.cs b/NPascalCoin/DTO/DecryptedPayloadDTO.cs
new file mode 100644
index 0000000..d92dee9
--- /dev/null
+++ b/NPascalCoin/DTO/DecryptedPayloadDTO.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+ ///
+ /// JSON object descibing a decrypted payload
+ ///
+ public class DecryptedPayloadDTO {
+ ///
+ /// Decryption result
+ ///
+ [JsonProperty("result")]
+ public bool Result { get; set; }
+
+ ///
+ /// HEXASTRING - Same value than param payload sent
+ ///
+ [JsonProperty("enc_payload")]
+ public string OriginalPayload { get; set; }
+
+ ///
+ /// Unencoded value in readable format (no HEXASTRING)
+ ///
+ [JsonProperty("unenc_payload")]
+ public string UnencryptedPayload { get; set; }
+
+ ///
+ /// HEXASTRING - Unencoded value in hexastring
+ ///
+ [JsonProperty("unenc_hexpayload")]
+ public string UnencryptedPayloadHex { get; set; }
+
+ ///
+ /// String - "key" or "pwd"
+ ///
+ [JsonProperty("payload_method")]
+ public PayloadMethod PayloadMethod { get; set; }
+
+ ///
+ /// HEXASTRING - Encoded public key used to decrypt when method = "key"
+ ///
+ [JsonProperty("enc_pubkey")]
+ public string EncodedPubKey { get; set; }
+
+ ///
+ /// String value used to decrypt when method = "pwd"
+ ///
+ [JsonProperty("pwd")]
+ public string DecryptPassword { get; set; }
+
+ }
+}
diff --git a/NPascalCoin/DTO/ErrorCode.cs b/NPascalCoin/DTO/ErrorCode.cs
new file mode 100644
index 0000000..4a6921f
--- /dev/null
+++ b/NPascalCoin/DTO/ErrorCode.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NPascalCoin.DTO {
+ public enum ErrorCode {
+ InternalError = 100,
+ MethodNotFound = 1001,
+ InvalidAccount = 1002,
+ InvalidBlock = 1003,
+ InvalidOperation = 1004,
+ InvalidPubKey = 1005,
+ NotFound = 1010,
+ WalletPasswordProtected = 1015,
+ InvalidData = 1016
+ }
+}
diff --git a/NPascalCoin/DTO/ErrorResultDTO.cs b/NPascalCoin/DTO/ErrorResultDTO.cs
new file mode 100644
index 0000000..c53f885
--- /dev/null
+++ b/NPascalCoin/DTO/ErrorResultDTO.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+ ///
+ /// JSON-RPC Error result
+ ///
+ public class ErrorResultDTO {
+ [JsonProperty("code")]
+ public ErrorCode ErrorCode { get; set; }
+
+ [JsonProperty("message")]
+ public string Message { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/DTO/KeyType.cs b/NPascalCoin/DTO/KeyType.cs
new file mode 100644
index 0000000..349409a
--- /dev/null
+++ b/NPascalCoin/DTO/KeyType.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// Type of key used for public/private key encryption.
+ ///
+ public enum KeyType {
+ ///
+ /// secp256k1
+ ///
+ SECP256K1 = 714,
+
+ ///
+ /// secp384r1
+ ///
+ SECP384R1 = 715,
+
+ ///
+ /// secp283k1
+ ///
+ SECP283K1 = 729,
+
+ ///
+ /// secp521r1
+ ///
+ SECP521R1 = 716,
+ }
+
+}
diff --git a/NPascalCoin/DTO/NetProtocolDTO.cs b/NPascalCoin/DTO/NetProtocolDTO.cs
new file mode 100644
index 0000000..3a3a40f
--- /dev/null
+++ b/NPascalCoin/DTO/NetProtocolDTO.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// Embedded JSON object describing node protocol support
+ ///
+ public class NetProtocolDTO {
+
+ ///
+ /// Net protocol version
+ ///
+ [JsonProperty("ver")]
+ public uint Version { get; set; }
+
+ ///
+ /// Net protocol available
+ ///
+ [JsonProperty("ver_a")]
+ public uint AvailableVersion { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/DTO/NetStatsDTO.cs b/NPascalCoin/DTO/NetStatsDTO.cs
new file mode 100644
index 0000000..2a2cdfe
--- /dev/null
+++ b/NPascalCoin/DTO/NetStatsDTO.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// Embedded JSON object describing node protocol support
+ ///
+ public class NetStatsDTO {
+
+ [JsonProperty("active")]
+ public uint Active { get; set; }
+
+ [JsonProperty("clients")]
+ public uint Clients { get; set; }
+
+ [JsonProperty("servers")]
+ public uint Servers { get; set; }
+
+ [JsonProperty("servers_t")]
+ public uint Servers_t { get; set; }
+
+ [JsonProperty("total")]
+ public uint Total { get; set; }
+
+ [JsonProperty("tclients")]
+ public uint TotalClients { get; set; }
+
+ [JsonProperty("tservers")]
+ public uint TotalServers { get; set; }
+
+ [JsonProperty("breceived")]
+ public uint BytesReceived { get; set; }
+
+ [JsonProperty("bsend")]
+ public uint BytesSent { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/DTO/NodeServerDTO.cs b/NPascalCoin/DTO/NodeServerDTO.cs
new file mode 100644
index 0000000..d13f3ed
--- /dev/null
+++ b/NPascalCoin/DTO/NodeServerDTO.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+ ///
+ /// Embedded JSON object describing a nodes list of servers
+ ///
+ public class NodeServerDTO {
+ [JsonProperty("ip")]
+ public string IP { get; set; }
+
+ [JsonProperty("port")]
+ public uint Port { get; set; }
+
+ [JsonProperty("lastcon")]
+ public uint LastConnect { get; set; }
+
+ [JsonProperty("attempts")]
+ public uint Attempts { get; set; }
+
+ }
+}
diff --git a/NPascalCoin/DTO/NodeStatusDTO.cs b/NPascalCoin/DTO/NodeStatusDTO.cs
new file mode 100644
index 0000000..3e2c0bb
--- /dev/null
+++ b/NPascalCoin/DTO/NodeStatusDTO.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// Information about node
+ ///
+ public class NodeStatusDTO {
+
+ ///
+ /// Must be true, otherwise Node is not ready to execute operations
+ ///
+ [JsonProperty("ready")]
+ public bool Ready { get; set; }
+
+ ///
+ /// Human readable information about ready or not
+ ///
+ [JsonProperty("ready_s")]
+ public string ReadyDescriptor { get; set; }
+
+
+ ///
+ /// Human readable information about node status...Running, downloading blockchain, discovering servers...
+ ///
+ [JsonProperty("status_s")]
+ public string StatusDescriptor { get; set; }
+
+ ///
+ /// Server port
+ ///
+ [JsonProperty("port")]
+ public uint Port { get; set; }
+
+ ///
+ /// True when this wallet is locked, false otherwise
+ ///
+ [JsonProperty("locked")]
+ public bool Locked { get; set; }
+
+ ///
+ /// Timestamp of the Node
+ ///
+ [JsonProperty("timestamp")]
+ public uint Timestamp { get; set; }
+
+ ///
+ /// Server version
+ ///
+ [JsonProperty("version")]
+ public string Version { get; set; }
+
+ ///
+ /// JSON Object with protocol versions
+ ///
+ [JsonProperty("netprotocol")]
+ public NetProtocolDTO NetProtocol { get; set; }
+
+ ///
+ /// Blockchain blocks
+ ///
+ [JsonProperty("blocks")]
+ public uint Blocks { get; set; }
+
+ ///
+ /// JSON Object with net information
+ ///
+ [JsonProperty("netstats")]
+ public NetStatsDTO NetStats { get; set; }
+
+
+ ///
+ /// JSON Array with servers candidates
+ ///
+ [JsonProperty("nodeservers")]
+ public NodeServerDTO[] NodeServers { get; set; }
+ }
+}
diff --git a/NPascalCoin/DTO/OperationDTO.cs b/NPascalCoin/DTO/OperationDTO.cs
new file mode 100644
index 0000000..da700de
--- /dev/null
+++ b/NPascalCoin/DTO/OperationDTO.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// An "Operation object" is a JSON object with information about an operation.
+ ///
+ public class OperationDTO {
+
+ ///
+ /// If operation is invalid, value=false (optional)
+ ///
+ [JsonProperty("valid")]
+ [DefaultValue(null)]
+ public bool? Valid { get; set; }
+
+ ///
+ /// If operation is invalid, an error description (optional)
+ ///
+ [JsonProperty("errors")]
+ [DefaultValue(null)]
+ public string Errors { get; set; }
+
+ ///
+ /// Block number (only when valid)
+ ///
+ [JsonProperty("block")]
+ public uint? Block { get; set; }
+
+ ///
+ /// Block timestamp (only when valid)
+ ///
+ [JsonProperty("time")]
+ [DefaultValue(null)]
+ public uint? Time { get; set; }
+
+ ///
+ /// Operation index inside a block(0..operations-1). Note: If opblock = -1 means that is a blockchain reward (only when valid)
+ ///
+ [JsonProperty("opblock")]
+ [DefaultValue(null)]
+ public int? OperationBlock { get; set; }
+
+ ///
+ /// Return null when operation is not included on a blockchain yet, 0 means that is included in highest block and so on... (New on Build 1.4.3)
+ ///
+ [JsonProperty("maturation")]
+ public uint Maturation { get; set; }
+
+ ///
+ /// Operation type.
+ ///
+ [JsonProperty("optype")]
+ public OperationType Type { get; set; }
+
+ ///
+ /// Account affected by this operation.Note: A transaction has 2 affected accounts.
+ ///
+ [JsonProperty("account")]
+ public int Account { get; set; }
+
+ ///
+ /// Account affected by this operation.Note: A transaction has 2 affected accounts.
+ ///
+ [JsonProperty("optxt")]
+ public string TypeDescriptor { get; set; }
+
+ ///
+ /// Amount of coins transferred from sender_account to dest_account (Only apply when optype = 1) (PASCURRENCY)
+ ///
+ [JsonProperty("amount")]
+ public decimal Amount { get; set; }
+
+ ///
+ /// Fee of this operation (PASCURRENCY)
+ ///
+ [JsonProperty("fee")]
+ public decimal Fee { get; set; }
+
+ ///
+ /// Balance of account after this block is introduced in the Blockchain (PASCURRENCY).
+ ///
+ ///
+ /// balance is a calculation based on current safebox account balance and previous operations, it's only returned on pending operations and account operations
+ ///
+ [JsonProperty("balance")]
+ public decimal Balance { get; set; }
+
+ ///
+ /// Sender account in a transaction (optype = 1)
+ ///
+ [JsonProperty("sender_account")]
+ public uint SenderAccount { get; set; }
+
+ ///
+ /// Destination account in a transaction (optype = 1)
+ ///
+ [JsonProperty("dest_account")]
+ public uint DestAccount { get; set; }
+
+ ///
+ /// Encoded public key in a change key operation(optype = 2). (HEXASTRING). See decodepubkey.
+ ///
+ [JsonProperty("enc_pubkey")]
+ public string EncPubKey { get; set; }
+
+ ///
+ /// Operation hash used to find this operation in the blockchain. (HEXASTRING).
+ ///
+ [JsonProperty("ophash")]
+ public string OPID { get; set; }
+ }
+}
diff --git a/NPascalCoin/DTO/OperationType.cs b/NPascalCoin/DTO/OperationType.cs
new file mode 100644
index 0000000..d9ea9dd
--- /dev/null
+++ b/NPascalCoin/DTO/OperationType.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NPascalCoin.DTO {
+ public enum OperationType {
+ ///
+ /// Blockchain reward
+ ///
+ BlockchainReward = 0,
+
+ ///
+ /// Transaction
+ ///
+ Transaction = 1,
+
+ ///
+ /// Change key
+ ///
+ ChangeKey = 2,
+
+ ///
+ /// Recover founds (lost keys)
+ ///
+ RecoverFunds = 3
+ }
+
+}
diff --git a/NPascalCoin/DTO/PayloadMethod.cs b/NPascalCoin/DTO/PayloadMethod.cs
new file mode 100644
index 0000000..defca20
--- /dev/null
+++ b/NPascalCoin/DTO/PayloadMethod.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// Type of payload encoded.
+ ///
+ public enum PayloadMethod {
+
+ ///
+ /// Not encoded. Will be visible for everybody
+ ///
+ [Description("none")]
+ None,
+
+ ///
+ /// Using Public key of "target" account. Only "target" will be able to decrypt this payload
+ ///
+ [Description("dest")]
+ Dest,
+
+ ///
+ /// Using sender Public key. Only "sender" will be able to decrypt this payload
+ ///
+ [Description("sender")]
+ Sender,
+
+ ///
+ /// Encrypted data using pwd param
+ ///
+ [Description("aes")]
+ Aes
+ }
+
+}
diff --git a/NPascalCoin/DTO/PublicKeyDTO.cs b/NPascalCoin/DTO/PublicKeyDTO.cs
new file mode 100644
index 0000000..e51bb2c
--- /dev/null
+++ b/NPascalCoin/DTO/PublicKeyDTO.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+ ///
+ /// A "Public Key object" is a JSON object with information about a public key.
+ ///
+ public class PublicKeyDTO {
+
+ ///
+ /// Human readable name stored at the Wallet for this key
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// If false then Wallet doesn't have Private key for this public key, so, Wallet cannot execute operations with this key
+ ///
+ [JsonProperty("can_use")]
+ public bool CanUse { get; set; }
+
+ ///
+ /// Encoded value of this public key.This HEXASTRING has no checksum, so, if using it always must be sure that value is correct
+ ///
+ [JsonProperty("enc_pubkey")]
+ public string EncPubKey { get; set; }
+
+ ///
+ /// Encoded value of this public key in Base 58 format, also contains a checksum.This is the same value that Application Wallet exports as a public key
+ ///
+ [JsonProperty("b58_pubkey")]
+ public string Base58PubKey { get; set; }
+
+ ///
+ /// Indicates which EC type is used (EC_NID)
+ ///
+ [JsonProperty("ec_nid")]
+ public KeyType KeyType { get; set; }
+
+ ///
+ /// HEXASTRING with x value of public key
+ ///
+ [JsonProperty("x")]
+ public string X { get; set; }
+
+ ///
+ /// HEXASTRING with y value of public key
+ ///
+ [JsonProperty("y")]
+ public string Y { get; set; }
+ }
+
+
+}
diff --git a/NPascalCoin/DTO/RawOperationDTO.cs b/NPascalCoin/DTO/RawOperationDTO.cs
new file mode 100644
index 0000000..abf49d8
--- /dev/null
+++ b/NPascalCoin/DTO/RawOperationDTO.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace NPascalCoin.DTO {
+
+
+ ///
+ /// A "Raw operations object" is a JSON object with information about a signed operation made by "signsendto" or "signchangekey"
+ ///
+ public class RawOperationDTO {
+
+ ///
+ /// Count how many operations has rawoperations param
+ ///
+ [JsonProperty("operations")]
+ public uint NumOperations { get; set; }
+
+ ///
+ /// Total amount
+ ///
+ [JsonProperty("amount")]
+ public decimal TotalAmount { get; set; }
+
+ ///
+ /// Total fee
+ ///
+ [JsonProperty("fee")]
+ public decimal TotalFee { get; set; }
+
+ ///
+ /// This is the operations in raw format.
+ ///
+ [JsonProperty("rawoperations")]
+ public string RawOperations { get; set; }
+ }
+
+}
diff --git a/NPascalCoin/NPascalCoin.csproj b/NPascalCoin/NPascalCoin.csproj
new file mode 100644
index 0000000..c046577
--- /dev/null
+++ b/NPascalCoin/NPascalCoin.csproj
@@ -0,0 +1,82 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {527FBE08-46AF-49C9-9479-FEFF1FA9EBF8}
+ Library
+ Properties
+ NPascalCoin
+ NPascalCoin
+ v4.6
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NPascalCoin/Properties/AssemblyInfo.cs b/NPascalCoin/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..09fb26d
--- /dev/null
+++ b/NPascalCoin/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("NPascalCoin")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NPascalCoin")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[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("527fbe08-46af-49c9-9479-feff1fa9ebf8")]
+
+// 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/NPascalCoin/RPC/ApiMethodName.cs b/NPascalCoin/RPC/ApiMethodName.cs
new file mode 100644
index 0000000..14d3567
--- /dev/null
+++ b/NPascalCoin/RPC/ApiMethodName.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NPascalCoin.DTO;
+
+namespace NPascalCoin {
+ internal enum ApiMethodName {
+ addnode,
+ getaccount,
+ getwalletaccounts,
+ getwalletaccountscount,
+ getwalletpubkeys,
+ getwalletpubkey,
+ getwalletcoins,
+ getblock,
+ getblocks,
+ getblockcount,
+ getblockoperation,
+ getblockoperations,
+ getaccountoperations,
+ getpendings,
+ findoperation,
+ sendto,
+ changekey,
+ changekeys,
+ signsendto,
+ signchangekey,
+ operationsinfo,
+ executeoperations,
+ nodestatus,
+ encodepubkey,
+ decodepubkey,
+ payloadencrypt,
+ payloaddecrypt,
+ getconnections,
+ addnewkey,
+ @lock,
+ unlock,
+ setwalletpassword,
+ stopnode,
+ startnode,
+ }
+}
diff --git a/NPascalCoin/RPC/IPascalCoinClient.cs b/NPascalCoin/RPC/IPascalCoinClient.cs
new file mode 100644
index 0000000..1bede2d
--- /dev/null
+++ b/NPascalCoin/RPC/IPascalCoinClient.cs
@@ -0,0 +1,333 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NPascalCoin.DTO;
+
+namespace NPascalCoin {
+ public interface IPascalCoinClient {
+
+ ///
+ /// Adds a node to connect
+ ///
+ /// String containing 1 or multiple IP:port separated by ";"
+ /// Returns an integer with nodes added
+ int AddNode(string nodes);
+
+ ///
+ /// Returns a JSON Object with account information including pending operations not included in blockchain yet, but affecting this account.
+ ///
+ ///
+ /// To know if there are pending operations, must look at updated_b param.It tells last block that modified this account.If this number is equal to blockchain blocks then this account is affected by pending operations (send/receive or change key)
+ ///
+ /// Cardinal containing account number
+ AccountDTO GetAccount(uint account);
+
+ ///
+ /// Returns a JSON array with all wallet accounts.
+ ///
+ /// HEXASTRING (optional). If provided, return only accounts of this public key
+ /// String (optional). If provided, return only accounts of this public key. Note: If use enc_pubkey and b58_pubkey together and is not the same public key, will return an error
+ /// Integer (optional, default = 0). If provided, will return wallet accounts starting at this position (index starts at position 0)
+ /// Integer (optional, default = 100). If provided, will return max accounts. If not provided, max=100 by default
+ /// Each JSON array item contains an Account Object
+ AccountDTO[] GetWalletAccounts(string enc_pubkey = null, string b58_pubkey = null, uint? start = null, uint? max = null);
+
+ ///
+ /// Get number of available wallet accounts (total or filtered by public key)
+ ///
+ /// HEXASTRING (optional). If provided, return only accounts of this public key
+ /// String (optional). If provided, return only accounts of this public key. Note: If use enc_pubkey and b58_pubkey together and is not the same public key, will return an error
+ /// Integer (optional, default = 0). If provided, will return wallet accounts starting at this position (index starts at position 0)
+ /// Integer (optional, default = 100). If provided, will return max accounts. If not provided, max=100 by default
+ /// Returns an integer with total
+ uint GetWalletAccountsCount(string enc_pubkey = null, string b58_pubkey = null, uint? start = null, uint? max = null);
+
+ ///
+ /// Returns a JSON Object with a public key if found in the Wallet
+ ///
+ /// HEXASTRING
+ /// String
+ /// Note: If use enc_pubkey and b58_pubkey together and is not the same public key, will return an error
+ /// Returns a JSON Object with a "Public Key Object"
+ PublicKeyDTO GetWalletPubKey(string enc_pubkey = null, string b58_pubkey = null);
+
+
+ ///
+ /// Returns a JSON Array with all pubkeys of the Wallet (address)
+ ///
+ /// Integer (optional, default = 0). If provided, will return wallet public keys starting at this position (index starts at position 0)
+ /// Integer (optional, default = 100). If provided, will return max public keys. If not provided, max=100 by default
+ /// Returns a JSON Array with "Public Key Object"
+ PublicKeyDTO[] GetWalletPubKeys(uint? start = null, uint? max = null);
+
+ ///
+ /// Returns coins balance.
+ ///
+ /// HEXASTRING (optional). If provided, return only this public key balance
+ /// String (optional). If provided, return only this public key balance If use enc_pubkey and b58_pubkey together and is not the same public key, will throw an error
+ /// Returns a PASCURRENCY value with maximum 4 decimals
+ decimal GetWalletCoins(string enc_pubkey = null, string b58_pubkey = null);
+
+ ///
+ /// Returns a JSON Object with a block information
+ ///
+ /// Block number (0..blocks count-1)
+ /// Returns a JSON Object with a "Block Object"
+ BlockDTO GetBlock(uint block);
+
+ ///
+ /// Returns a JSON Array with blocks information from "start" to "end" (or "last" n blocks) Blocks are returned in DESCENDING order. See
+ ///
+ /// Last n blocks in the blockchain (n>0 and n<=1000)
+ /// From this block
+ /// To this block
+ /// Must use last exclusively, or start and end, or error
+ ///
+ BlockDTO[] GetBlocks(uint? last = null, uint? start = null, uint? end = null);
+
+ ///
+ /// Returns an Integer with blockcount of node
+ ///
+ /// Total blocks
+ uint GetBlockCount();
+
+ ///
+ /// Returns a JSON Object with an operation inside a block
+ ///
+ /// Block number
+ /// Operation (0..operations-1) of this block
+ /// JSON Object with a "Operation Object"
+ OperationDTO GetBlockOperation(uint block, uint opblock);
+
+ ///
+ /// Returns a JSON Array with all operations of specified block Operations are returned in DESCENDING order
+ ///
+ /// Block number
+ /// Integer (optional, default = 0). If provided, will start at this position (index starts at position 0)
+ /// Integer (optional, default = 100). If provided, will return max registers. If not provided, max=100 by default
+ /// Returns a JSON Array with "Operation Object" items
+ OperationDTO[] GetBlockOperations(uint block, uint? start = null, uint? max = null);
+
+ ///
+ /// Return a JSON Array with "Operation Object" items. Operations made over an account Operations are returned in DESCENDING order
+ ///
+ /// Account number (0..accounts count-1)
+ /// Integer - (Optional, default value 100) Depth to search on blocks where this account has been affected. Allowed to use deep as a param name too.
+ /// Integer (optional, default = 0). If provided, will start at this position (index starts at position 0). If start is -1, then will include pending operations, otherwise only operations included on the blockchain
+ /// Integer (optional, default = 100). If provided, will return max registers. If not provided, max=100 by default
+ /// Returns an array holding operations made over account in "Operation Object" format
+ OperationDTO[] GetAccountOperations(uint account, uint? depth = null, uint? start = null, uint? max = null);
+
+ ///
+ /// Return a JSON Array with "Operation Object" items with operations pending to be included at the Blockchain.
+ ///
+ /// Returns an array holding pending operations in "Operation Object" format
+ OperationDTO[] GetPendings();
+
+ ///
+ /// Return a JSON Object in "Operation Object" format.
+ ///
+ /// HEXASTRING - Value ophash received on an operation
+ /// Returns "Operation Object" format JSON object
+ OperationDTO FindOperation(string ophash);
+
+
+ ///
+ /// Executes a transaction operation from "sender" to "target"
+ ///
+ /// Sender account
+ /// Destination account
+ /// Coins to be transferred
+ /// Fee of the operation
+ /// Payload "item" that will be included in this operation
+ /// Used to encrypt payload with aes as a payload_method. If none equals to empty password
+ /// If transaction is successfull will return a JSON Object in "Operation Object" format. Otherwise, will return a JSON-RPC error code with description
+ OperationDTO SendTo(uint sender, uint target, decimal amount, decimal fee, PayloadMethod? payloadMethod = null, string pwd = null);
+
+
+ ///
+ /// Executes a change key operation, changing "account" public key for a new one.
+ ///
+ /// Note that new one public key can be another Wallet public key, or none.When none, it's like a transaction, tranferring account owner to an external owner
+ /// Account number to change key
+ /// HEXASTRING - New public key in encoded format
+ /// New public key in Base 58 format (the same that Application Wallet exports)
+ /// PASCURRENCY - Fee of the operation
+ /// HEXASTRING - Payload "item" that will be included in this operation
+ /// Encode type of the item payload
+ /// Used to encrypt payload with aes as a payload_method. If none equals to empty password
+ /// If operation is successfull will return a JSON Object in "Operation Object" format. Otherwise, will return a JSON-RPC error code with description
+ OperationDTO ChangeKey(uint account, string new_enc_pubkey, string new_b58_pubkey, decimal fee, string payload, PayloadMethod? payloadMethod = null, string pwd = null);
+
+
+ ///
+ /// Executes a change key operation, changing "account" public key for a new one, in multiple accounts Works like changekey
+ ///
+ /// List of accounts separated by a comma
+ /// HEXASTRING - New public key in encoded format
+ /// New public key in Base 58 format (the same that Application Wallet exports)
+ /// PASCURRENCY - Fee of the operation
+ /// HEXASTRING - Payload "item" that will be included in this operation
+ /// Encode type of the item payload
+ /// Used to encrypt payload with aes as a payload_method. If none equals to empty password
+ /// If operation is successfull will return a JSON Array with Operation object items for each key If operation cannot be made, a JSON-RPC error message is returned
+ OperationDTO[] ChangeKeys(string accounts, string new_enc_pubkey, string new_b58_pubkey, decimal fee, string payload, PayloadMethod? payloadMethod = null, string pwd = null);
+
+
+ ///
+ /// Creates and signs a "Send to" operation without checking information and without transfering to the network. It's usefull for "cold wallets" that are off-line (not synchronized with the network) and only holds private keys
+ ///
+ /// Sender account
+ /// Target account
+ /// HEXASTRING - Public key of the sender account in encoded format
+ /// HEXASTRING - Public key of the sender account in base58 format
+ /// HEXASTRING - Public key of the target account in encoded format
+ /// HEXASTRING - Public key of the target account in base58 format
+ /// Last value of n_operation obtained with an Account object, for example when called to getaccount
+ /// Coins to be transferred
+ /// Fee of the operation
+ /// Payload "item" that will be included in this operation
+ /// Used to encrypt payload with aes as a payload_method. If none equals to empty password
+ /// HEXASTRING (optional) - If we want to add a sign operation with other previous operations, here we must put previous rawoperations result
+ /// Wallet must be unlocked and sender private key (searched with provided public key) must be in wallet. No other checks are made (no checks for valid target, valid n_operation, valid amount or fee ...)
+ /// Only one of sender_enc_pubkey, sender_b58_pubkey needs be provided
+ /// Only one of target_enc_pubkey, target_b58_pubkey needs be provided
+ /// Returns a Raw Operations Object
+ RawOperationDTO SignSendTo(uint sender, uint target, string sender_enc_pubkey, string sender_b58_pubkey, string target_enc_pubkey, string target_b58_pubkey, uint last_n_operation, decimal amount, decimal fee, PayloadMethod? payloadMethod = null, string pwd = null, string rawoperations = null);
+
+
+ ///
+ /// Creates and signs a "Change key" operation without checking information and without transfering to the network. It's usefull for "cold wallets" that are off-line (not synchronized with the network) and only holds private keys
+ ///
+ /// Account number to change key
+ /// HEXASTRING - Public key of the account in encoded format
+ /// HEXASTRING - Public key of the account in base58 format
+ /// HEXASTRING - Public key of the new key for the account in encoded format
+ /// HEXASTRING - Public key of the new key for the account in base58 format
+ /// Last value of n_operation obtained with an Account object, for example when called to getaccount
+ /// Fee of the operation
+ /// Payload "item" that will be included in this operation
+ /// Used to encrypt payload with aes as a payload_method. If none equals to empty password
+ /// HEXASTRING (optional) - If we want to add a sign operation with other previous operations, here we must put previous rawoperations result
+ /// Wallet must be unlocked and private key (searched with provided public key) must be in wallet. No other checks are made (no checks for valid n_operation, valid fee ...)
+ /// Only one of old_enc_pubkey, old_b58_pubkey needs be provided
+ /// Only one of new_enc_pubkey, new_b58_pubkey needs be provided
+ /// Wallet must be unlocked and private key (searched with provided public key) must be in wallet. No other checks are made (no checks for valid n_operation, valid fee ...) Returns a Raw Operations Object
+ RawOperationDTO SignChangeKey(uint account, string old_enc_pubkey, string old_b58_pubkey, string new_enc_pubkey, string new_b58_pubkey, uint last_n_operation, decimal fee, PayloadMethod? payloadMethod = null, string pwd = null, string rawoperations = null);
+
+ ///
+ /// Returns information stored in a rawoperations param (obtained calling signchangekey or signsendto)
+ ///
+ /// HEXASTRING (obtained calling signchangekey or signsendto)
+ /// Returns a JSON Array with Operation Object items, one for each operation in rawoperations param. NOTE: Remember that rawoperations are operations that maybe are not correct
+ OperationDTO[] OperationsInfo(string rawoperations);
+
+ ///
+ /// Executes operations included in rawopertions param and transfers to the network. Raw operations can include "Send to" oprations or "Change key" operations.
+ ///
+ /// Executes operations included in rawopertions param and transfers to the network. Raw operations can include "Send to" oprations or "Change key" operations.
+ /// For each Operation Object item, if there is an error, param valid will be false and param errors will show error description.Otherwise, operation is correct and will contain ophash param
+ /// Returns a JSON Array with Operation Object items, one for each operation in rawoperations param.
+ OperationDTO[] ExecuteOperations(string rawoperations);
+
+
+ ///
+ /// Returns information of the Node in a JSON Object
+ ///
+ /// JSON Object with information
+ NodeStatusDTO NodeStatus();
+
+
+ ///
+ /// Encodes a public key based on params information
+ ///
+ /// key type
+ /// HEXASTRING with x value of public key
+ /// HEXASTRING with y value of public key
+ /// Returns a HEXASTRING with encoded public key
+ string EncodePubKey(KeyType ec_nid, string x, string y);
+
+
+ ///
+ /// Decodes an encoded public key
+ ///
+ /// HEXASTRING with encoded public key
+ /// String. b58_pubkey is the same value that Application Wallet exports as a public key
+ /// Note: If use enc_pubkey and b58_pubkey together and is not the same public key, will return an error
+ /// Returns a JSON Object with a "Public Key Object"
+ PublicKeyDTO DecodePubKey(string enc_pubkey, string b58_pubkey);
+
+
+ ///
+ /// Encrypt a text "paylad" using "payload_method"
+ ///
+ /// HEXASTRING - Text to encrypt in hexadecimal format
+ /// Payload method
+ /// Using a Password. Must provide pwd param
+ /// Returns a HEXASTRING with encrypted payload
+ string PayloadEncrypt(string payload, PayloadMethod payload_method, string pwd);
+
+
+ ///
+ /// Returns a HEXASTRING with decrypted text (a payload) using private keys in the wallet or a list of Passwords (used in "aes" encryption)
+ ///
+ /// HEXASTRING - Encrypted data
+ /// List of passwords to use
+ /// If using one of private keys is able to decrypt payload then returns value "key" in payload_method and enc_pubkey contains encoded public key in HEXASTRING
+ /// If using one of passwords to decrypt payload then returns value "pwd" in payload_method and pwd contains password used
+ /// Decryped payload
+ DecryptedPayloadDTO PayloadDecrypt(string payload, string[] pwds = null);
+
+ ///
+ /// Returns all the current connections
+ ///
+ /// JSON Array with Connection Objects
+ ConnectionDTO[] GetConnections();
+
+
+ ///
+ /// Creates a new Private key and sotres it on the wallet, returning an enc_pubkey value
+ ///
+ /// Type of key encryption
+ /// Name to alias this new private key
+ ///
+ PublicKeyDTO AddNewKey(KeyType ec_nid, string name);
+
+ ///
+ /// Locks the Wallet if it has a password, otherwise wallet cannot be locked
+ ///
+ /// Returns a Boolean indicating if Wallet is locked. If false that means that Wallet has an empty password and cannot be locked
+ bool Lock();
+
+ ///
+ /// Unlocks a locked Wallet using "pwd" param
+ ///
+ ///
+ /// Returns a Boolean indicating if Wallet is unlocked after using pwd password
+ bool Unlock(string pwd);
+
+
+ ///
+ /// Changes the password of the Wallet. (Must be previously unlocked) Note: If pwd param is empty string, then wallet will be not protected by password
+ ///
+ /// New password
+ /// Returns a Boolean if Wallet password changed with new pwd password
+ bool SetWalletPassword(string pwd);
+
+ ///
+ /// Stops the node and the server. Closes all connections
+ ///
+ ///
+ bool StopNode();
+
+ ///
+ /// Starts the node and the server. Starts connection process
+ ///
+ /// Boolean "true"
+ bool StartNode();
+
+ }
+}
diff --git a/NPascalCoin/RPC/PascalCoinClient.cs b/NPascalCoin/RPC/PascalCoinClient.cs
new file mode 100644
index 0000000..9023fac
--- /dev/null
+++ b/NPascalCoin/RPC/PascalCoinClient.cs
@@ -0,0 +1,395 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using NPascalCoin.DTO;
+
+namespace NPascalCoin {
+ public class PascalCoinClient : IPascalCoinClient {
+ private readonly Uri _url;
+ private int _callID;
+
+ public PascalCoinClient(string server, int port) {
+ _url = new Uri($"http://{server}:{port}");
+ _callID = 0;
+ }
+
+ public int AddNode(string nodes) {
+ return Invoke(ApiMethodName.addnode.ToString(), new Dictionary() {
+ ["nodes"] = nodes
+ });
+ }
+
+ public AccountDTO GetAccount(uint account) {
+ return Invoke(ApiMethodName.getaccount.ToString(), new Dictionary() {
+ ["account"] = account
+ });
+
+ }
+
+ public AccountDTO[] GetWalletAccounts(string enc_pubkey = null, string b58_pubkey = null, uint? start = null, uint? max = null) {
+ return Invoke(ApiMethodName.getwalletaccounts.ToString(), new Dictionary() {
+ ["enc_pubkey"] = enc_pubkey,
+ ["b58_pubkey"] = b58_pubkey,
+ ["start"] = start,
+ ["max"] = max,
+ });
+ }
+
+ public uint GetWalletAccountsCount(string enc_pubkey = null, string b58_pubkey = null, uint? start = null, uint? max = null) {
+ return Invoke(ApiMethodName.getwalletaccountscount.ToString(), new Dictionary() {
+ ["enc_pubkey"] = enc_pubkey,
+ ["b58_pubkey"] = b58_pubkey,
+ ["start"] = start,
+ ["max"] = max,
+ });
+ }
+
+ public PublicKeyDTO GetWalletPubKey(string enc_pubkey = null, string b58_pubkey = null) {
+ return Invoke(ApiMethodName.getwalletpubkey.ToString(), new Dictionary() {
+ ["enc_pubkey"] = enc_pubkey,
+ ["b58_pubkey"] = b58_pubkey
+ });
+ }
+
+ public PublicKeyDTO[] GetWalletPubKeys(uint? start = null, uint? max = null) {
+ return Invoke(ApiMethodName.getwalletpubkeys.ToString(), new Dictionary() {
+ ["start"] = start,
+ ["max"] = max,
+ });
+ }
+
+ public decimal GetWalletCoins(string enc_pubkey = null, string b58_pubkey = null) {
+ return Invoke(ApiMethodName.getwalletcoins.ToString(), new Dictionary() {
+ ["enc_pubkey"] = enc_pubkey,
+ ["b58_pubkey"] = b58_pubkey,
+ });
+ }
+
+ public BlockDTO GetBlock(uint block) {
+ return Invoke(ApiMethodName.getblock.ToString(), new Dictionary {
+ ["block"] = block
+ });
+ }
+
+ public BlockDTO[] GetBlocks(uint? last = null, uint? start = null, uint? end = null) {
+ return Invoke(ApiMethodName.getblocks.ToString(), new Dictionary {
+ ["last"] = last,
+ ["start"] = start,
+ ["end"] = end,
+ });
+ }
+
+ public uint GetBlockCount() {
+ return Invoke(ApiMethodName.getblockcount.ToString());
+ }
+
+ public OperationDTO GetBlockOperation(uint block, uint opblock) {
+ return Invoke(ApiMethodName.getblockoperation.ToString(), new Dictionary() {
+ ["block"] = block,
+ ["opblock"] = opblock,
+ });
+ }
+
+ public OperationDTO[] GetBlockOperations(uint block, uint? start = null, uint? max = null) {
+ return Invoke(ApiMethodName.getblockoperations.ToString(), new Dictionary() {
+ ["block"] = block,
+ ["start"] = start,
+ ["max"] = max,
+ });
+ }
+
+ public OperationDTO[] GetAccountOperations(uint account, uint? depth = null, uint? start = null, uint? max = null) {
+ return Invoke(ApiMethodName.getaccountoperations.ToString(), new Dictionary() {
+ ["account"] = account,
+ ["depth"] = depth,
+ ["start"] = start,
+ ["max"] = max,
+ });
+ }
+
+ public OperationDTO[] GetPendings() {
+ return Invoke(ApiMethodName.getpendings.ToString());
+ }
+
+ public OperationDTO FindOperation(string ophash) {
+ return Invoke(ApiMethodName.findoperation.ToString(), new Dictionary() {
+ ["ophash"] = ophash
+ });
+ }
+
+ public OperationDTO SendTo(uint sender, uint target, decimal amount, decimal fee, PayloadMethod? payloadMethod = null, string pwd = null) {
+ return Invoke(ApiMethodName.sendto.ToString(), new Dictionary() {
+ ["sender"] = sender,
+ ["target"] = target,
+ ["amount"] = amount,
+ ["fee"] = fee,
+ ["payloadMethod"] = payloadMethod,
+ ["pwd"] = pwd
+ });
+ }
+
+ public OperationDTO ChangeKey(uint account, string new_enc_pubkey, string new_b58_pubkey, decimal fee, string payload, PayloadMethod? payloadMethod = null, string pwd = null) {
+ return Invoke(ApiMethodName.changekey.ToString(), new Dictionary() {
+ ["account"] = account,
+ ["new_enc_pubkey"] = new_enc_pubkey,
+ ["new_b58_pubkey"] = new_b58_pubkey,
+ ["fee"] = fee,
+ ["payloadMethod"] = payloadMethod,
+ ["pwd"] = pwd
+ });
+ }
+
+ public OperationDTO[] ChangeKeys(string accounts, string new_enc_pubkey, string new_b58_pubkey, decimal fee, string payload, PayloadMethod? payloadMethod = null, string pwd = null) {
+ return Invoke(ApiMethodName.changekeys.ToString(), new Dictionary() {
+ ["accounts"] = accounts,
+ ["new_enc_pubkey"] = new_enc_pubkey,
+ ["new_b58_pubkey"] = new_b58_pubkey,
+ ["fee"] = fee,
+ ["payloadMethod"] = payloadMethod,
+ ["pwd"] = pwd,
+ });
+ }
+
+ public RawOperationDTO SignSendTo(uint sender, uint target, string sender_enc_pubkey, string sender_b58_pubkey, string target_enc_pubkey, string target_b58_pubkey, uint last_n_operation, decimal amount, decimal fee, PayloadMethod? payloadMethod = null, string pwd = null, string rawoperations = null) {
+ return Invoke(ApiMethodName.signsendto.ToString(), new Dictionary() {
+ ["rawoperations"] = rawoperations,
+ ["sender"] = sender,
+ ["target"] = target,
+ ["sender_enc_pubkey"] = sender_enc_pubkey,
+ ["sender_b58_pubkey"] = sender_b58_pubkey,
+ ["target_enc_pubkey"] = target_enc_pubkey,
+ ["target_b58_pubkey"] = target_b58_pubkey,
+ ["last_n_operation"] = last_n_operation,
+ ["amount"] = amount,
+ ["fee"] = fee,
+ ["payloadMethod"] = fee,
+ ["pwd"] = fee,
+ });
+ }
+
+ public RawOperationDTO SignChangeKey(uint account, string old_enc_pubkey, string old_b58_pubkey, string new_enc_pubkey, string new_b58_pubkey, uint last_n_operation, decimal fee, PayloadMethod? payloadMethod = null, string pwd = null, string rawoperations = null) {
+ return Invoke(ApiMethodName.signchangekey.ToString(), new Dictionary() {
+ ["rawoperations"] = rawoperations,
+ ["account"] = account,
+ ["old_enc_pubkey"] = old_enc_pubkey,
+ ["old_b58_pubkey"] = old_b58_pubkey,
+ ["new_enc_pubkey"] = new_enc_pubkey,
+ ["new_b58_pubkey"] = new_b58_pubkey,
+ ["last_n_operation"] = last_n_operation,
+ ["fee"] = fee,
+ ["payloadMethod"] = fee,
+ ["pwd"] = fee,
+ });
+ }
+
+ public OperationDTO[] OperationsInfo(string rawoperations) {
+ return Invoke(ApiMethodName.operationsinfo.ToString(), new Dictionary() {
+ ["rawoperations"] = rawoperations
+ });
+ }
+
+ public OperationDTO[] ExecuteOperations(string rawoperations) {
+ return Invoke(ApiMethodName.executeoperations.ToString(), new Dictionary() {
+ ["rawoperations"] = rawoperations
+ });
+ }
+
+ public NodeStatusDTO NodeStatus() {
+ return Invoke(ApiMethodName.nodestatus.ToString());
+ }
+
+ public string EncodePubKey(KeyType ec_nid, string x, string y) {
+ return Invoke(ApiMethodName.encodepubkey.ToString(), new Dictionary() {
+ ["ec_nid"] = ec_nid,
+ ["x"] = x,
+ ["y"] = y,
+ });
+ }
+
+ public PublicKeyDTO DecodePubKey(string enc_pubkey, string b58_pubkey) {
+ return Invoke(ApiMethodName.decodepubkey.ToString(), new Dictionary() {
+ ["enc_pubkey"] = enc_pubkey,
+ ["b58_pubkey"] = b58_pubkey,
+ });
+ }
+
+ public string PayloadEncrypt(string payload, PayloadMethod payload_method, string pwd) {
+ return Invoke(ApiMethodName.payloadencrypt.ToString(), new Dictionary() {
+ ["payload"] = payload,
+ ["payload_method"] = payload_method,
+ ["pwd"] = pwd
+ });
+ }
+
+ public DecryptedPayloadDTO PayloadDecrypt(string payload, string[] pwds = null) {
+ return Invoke(ApiMethodName.payloaddecrypt.ToString(), new Dictionary() {
+ ["payload"] = payload,
+ ["pwds"] = pwds,
+ });
+ }
+
+ public ConnectionDTO[] GetConnections() {
+ return Invoke(ApiMethodName.getconnections.ToString());
+ }
+
+ public PublicKeyDTO AddNewKey(KeyType ec_nid, string name) {
+ return Invoke(ApiMethodName.addnewkey.ToString(), new Dictionary() {
+ ["ec_nid"] = ec_nid,
+ ["name"] = name,
+ });
+ }
+
+ public bool Lock() {
+ return Invoke(ApiMethodName.@lock.ToString());
+ }
+
+ public bool Unlock(string pwd) {
+ return Invoke(ApiMethodName.unlock.ToString(), new Dictionary() {
+ ["pwd"] = pwd
+ });
+ }
+
+ public bool SetWalletPassword(string pwd) {
+ return Invoke(ApiMethodName.setwalletpassword.ToString(), new Dictionary() {
+ ["pwd"] = pwd
+ });
+ }
+
+ public bool StopNode() {
+ return Invoke(ApiMethodName.stopnode.ToString());
+ }
+
+ public bool StartNode() {
+ return Invoke(ApiMethodName.startnode.ToString());
+ }
+
+
+ protected virtual T Invoke_del(string method, IDictionary arguments = null) {
+ using (var callScope = new CallScope(this)) {
+ var webClient = new WebClient();
+ webClient.Headers.Set(HttpRequestHeader.UserAgent, "NPascalCoin v0.1");
+ webClient.Headers.Set(HttpRequestHeader.ContentType, "application/json-rpc");
+ //webClient.Headers.Set(HttpRequestHeader.);
+
+ var request = new JObject {
+ ["jsonrpc"] = "2.0",
+ ["id"] = callScope.CallID,
+ ["method"] = method
+ };
+
+ if (arguments?.Count > 0) {
+ var @params = new JArray();
+ foreach (var param in arguments.Where(x => x.Value != null)) {
+ @params.Add(new JProperty(param.Key, param.Value));
+ }
+ request.Add(new JProperty("params", @params));
+ }
+
+ var requestJson = JsonConvert.SerializeObject(request);
+ Trace.WriteLine($"RPC Request:{Environment.NewLine}{requestJson}", TraceCategories.RPC);
+
+ try {
+ var responseJson = webClient.UploadString(_url, "POST", requestJson);
+ Trace.WriteLine($"RPC Response:{Environment.NewLine}{responseJson}", TraceCategories.RPC);
+ return JsonConvert.DeserializeObject(responseJson);
+ } catch (WebException error) {
+ if (error.Response == null)
+ throw;
+ var resp = new StreamReader(error.Response.GetResponseStream()).ReadToEnd();
+ var errorDTO = JsonConvert.DeserializeObject(resp);
+ throw new PascalCoinRPCException(errorDTO);
+ }
+ }
+ }
+
+ protected virtual T Invoke(string method, IDictionary arguments = null) {
+ using (var callScope = new CallScope(this)) {
+ var webRequest = (HttpWebRequest)WebRequest.Create(_url);
+ webRequest.ProtocolVersion = System.Net.HttpVersion.Version11;
+ webRequest.UserAgent = $"NPascalCoin {Constants.NPascalCoinVersion}";
+ webRequest.ContentType = "application/json-rpc";
+ webRequest.Method = "POST";
+
+ var request = new JObject {
+ ["jsonrpc"] = "2.0",
+ ["id"] = callScope.CallID,
+ ["method"] = method
+ };
+
+ if (arguments?.Count > 0) {
+ var @params = new JArray();
+ foreach (var param in arguments.Where(x => x.Value != null)) {
+ @params.Add(new JProperty(param.Key, param.Value));
+ }
+ request.Add(new JProperty("params", @params));
+ }
+
+ var requestJson = JsonConvert.SerializeObject(request);
+ Trace.WriteLine($"RPC Request:{Environment.NewLine}{requestJson}", TraceCategories.RPC);
+
+
+ // serialize json for the request
+ var requestBytes = Encoding.UTF8.GetBytes(requestJson);
+ webRequest.ContentLength = requestBytes.Length;
+ using (var requestStream = webRequest.GetRequestStream()) {
+ requestStream.Write(requestBytes, 0, requestBytes.Length);
+ }
+ try {
+ using (var webResponse = webRequest.GetResponse()) {
+ using (var responseStream = webResponse.GetResponseStream()) {
+ using (var sr = new StreamReader(responseStream)) {
+ var responseJson = sr.ReadToEnd();
+ Trace.WriteLine($"RPC Response:{Environment.NewLine}{responseJson}", TraceCategories.RPC);
+ var jsonResponse = JsonConvert.DeserializeObject(responseJson);
+ if (jsonResponse.RPCVersion != "2.0")
+ throw new ApplicationException($"JSON-RPC response was an invalid version '{jsonResponse.RPCVersion ?? string.Empty}'. Expected '2.0'");
+ if (jsonResponse.ID != callScope.CallID)
+ throw new ApplicationException($"JSON-RPC response ID had invalid value '{jsonResponse.ID}'. Expected '{callScope.CallID}'");
+ return JsonConvert.DeserializeObject(jsonResponse.Result);
+ }
+ }
+ }
+ } catch (WebException error) {
+ if (error.Response == null)
+ throw;
+ var resp = new StreamReader(error.Response.GetResponseStream()).ReadToEnd();
+ var errorDTO = JsonConvert.DeserializeObject(resp);
+ throw new PascalCoinRPCException(errorDTO);
+ }
+ }
+ }
+
+ protected class CallScope : IDisposable {
+ private readonly PascalCoinClient _client;
+ public readonly int CallID;
+ public CallScope(PascalCoinClient client) {
+ _client = client;
+ CallID = Interlocked.Increment(ref _client._callID);
+ }
+
+ public void Dispose() {
+ Interlocked.Decrement(ref _client._callID);
+ }
+ }
+
+ private class JsonRpcResponse {
+ [JsonProperty("jsonrpc")]
+ public string RPCVersion { get; set; }
+
+ [JsonProperty("id")]
+ public int ID { get; set; }
+
+ [JsonProperty("result")]
+ public string Result { get; set; }
+ }
+ }
+}
diff --git a/NPascalCoin/RPC/PascalCoinRPCException.cs b/NPascalCoin/RPC/PascalCoinRPCException.cs
new file mode 100644
index 0000000..d98d184
--- /dev/null
+++ b/NPascalCoin/RPC/PascalCoinRPCException.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using NPascalCoin.DTO;
+
+namespace NPascalCoin {
+ public class PascalCoinRPCException : ApplicationException {
+ public PascalCoinRPCException(ErrorResultDTO result) : base($"{result.ErrorCode} - {result.Message}") {
+ Error = result;
+ }
+
+ public ErrorResultDTO Error { get; }
+
+ }
+}
diff --git a/NPascalCoin/TraceCategories.cs b/NPascalCoin/TraceCategories.cs
new file mode 100644
index 0000000..7220b19
--- /dev/null
+++ b/NPascalCoin/TraceCategories.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NPascalCoin {
+ internal static class TraceCategories {
+ public const string RPC = "NPascalCoin.RPC";
+ }
+}
diff --git a/NPascalCoin/packages.config b/NPascalCoin/packages.config
new file mode 100644
index 0000000..b34dd25
--- /dev/null
+++ b/NPascalCoin/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..dc6b816
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+#NPascalCoin
+
+NPascalCoin is a .NET library for PascalCoin. Currently, it supports the full JSON-RPC api. In future, it will contain the full network protcol.