C# client library for EOSIO blockchains. The library is based on https://github.com/EOSIO/eosjs and MIT licensed.
Install-Package eos-sharp
Visual Studio 2017+
eos-sharp is now available through nuget https://www.nuget.org/packages/eos-sharp
Install-Package eos-sharp
In order to interact with eos blockchain you need to create a new instance of the Eos class with a EosConfigurator.
Example:
Eos eos = new Eos(new EosConfigurator()
{
HttpEndpoint = "https://nodes.eos42.io", //Mainnet
ChainId = "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906",
ExpireSeconds = 60,
SignProvider = new DefaultSignProvider("myprivatekey")
});
GetInfo call
var result = await eos.GetInfo();
Returns:
class GetInfoResponse
{
string server_version;
string chain_id;
UInt32 head_block_num;
UInt32 last_irreversible_block_num;
string last_irreversible_block_id;
string head_block_id;
DateTime head_block_time;
string head_block_producer;
string virtual_block_cpu_limit;
string virtual_block_net_limit;
string block_cpu_limit;
string block_net_limit;
}
GetAccount call
var result = await eos.GetAccount("myaccountname");
Returns:
class GetAccountResponse
{
string account_name;
UInt32 head_block_num;
DateTime head_block_time;
bool privileged;
DateTime last_code_update;
DateTime created;
Int64 ram_quota;
Int64 net_weight;
Int64 cpu_weight;
Resource net_limit;
Resource cpu_limit;
UInt64 ram_usage;
List<Permission> permissions;
RefundRequest refund_request;
SelfDelegatedBandwidth self_delegated_bandwidth;
TotalResources total_resources;
VoterInfo voter_info;
}
GetBlock call
var result = await eos.GetBlock("blockIdOrNumber");
Returns:
class GetBlockResponse
{
DateTime timestamp;
string producer;
UInt32 confirmed;
string previous;
string transaction_mroot;
string action_mroot;
UInt32 schedule_version;
Schedule new_producers;
List<Extension> block_extensions;
List<Extension> header_extensions;
string producer_signature;
List<TransactionReceipt> transactions;
string id;
UInt32 block_num;
UInt32 ref_block_prefix;
}
GetTableRows call
var result = await eos.GetTableRows(new GetTableRowsRequest() {
json = true,
code = "eosio.token",
scope = "EOS",
table = "stat"
});
Returns:
class GetTableRowsResponse
{
List<object> rows
bool? more
}
Using generic type
/*JsonProperty helps map the fields from the api*/
public class Stat
{
public string issuer { get; set; }
public string max_supply { get; set; }
public string supply { get; set; }
}
var result = await Eos.GetTableRows<Stat>(new GetTableRowsRequest()
{
json = true,
code = "eosio.token",
scope = "EOS",
table = "stat"
});
Returns:
class GetTableRowsResponse<Stat>
{
List<Stat> rows
bool? more
}
var result = await eos.GetTableByScope(new GetTableByScopeRequest() {
code = "eosio.token",
table = "accounts"
});
Returns:
class GetTableByScopeResponse
{
List<TableByScopeResultRow> rows
string more
}
class TableByScopeResultRow
{
string code;
string scope;
string table;
string payer;
UInt32? count;
}
var result = await eos.GetActions("myaccountname", 0, 10);
Returns:
class GetActionsResponse
{
List<GlobalAction> actions;
UInt32 last_irreversible_block;
bool time_limit_exceeded_error;
}
NOTE: using anonymous objects and / or properties as action data is not supported on WEBGL Unity exports Use data as dictionary or strongly typed objects with fields.
var result = await eos.CreateTransaction(new Transaction()
{
actions = new List<Api.v1.Action>()
{
new Api.v1.Action()
{
account = "eosio.token",
authorization = new List<PermissionLevel>()
{
new PermissionLevel() {actor = "tester112345", permission = "active" }
},
name = "transfer",
data = new { from = "tester112345", to = "tester212345", quantity = "0.0001 EOS", memo = "hello crypto world!" }
}
}
});
Data can also be a Dictionary with key as string. The dictionary value can be any object with nested Dictionaries
var result = await eos.CreateTransaction(new Transaction()
{
actions = new List<Api.v1.Action>()
{
new Api.v1.Action()
{
account = "eosio.token",
authorization = new List<PermissionLevel>()
{
new PermissionLevel() {actor = "tester112345", permission = "active" }
},
name = "transfer",
data = new Dictionary<string, string>()
{
{ "from", "tester112345" },
{ "to", "tester212345" },
{ "quantity", "0.0001 EOS" },
{ "memo", "hello crypto world!" }
}
}
}
});
Returns the transactionId
Is also possible to implement your own ISignProvider to customize how the signatures and key handling is done.
Example:
/// <summary>
/// Signature provider implementation that uses a private server to hold keys
/// </summary>
class SuperSecretSignProvider : ISignProvider
{
/// <summary>
/// Get available public keys from signature provider server
/// </summary>
/// <returns>List of public keys</returns>
public async Task<IEnumerable<string>> GetAvailableKeys()
{
var result = await HttpHelper.GetJsonAsync<SecretResponse>("https://supersecretserver.com/get_available_keys");
return result.Keys;
}
/// <summary>
/// Sign bytes using the signature provider server
/// </summary>
/// <param name="chainId">EOSIO Chain id</param>
/// <param name="requiredKeys">required public keys for signing this bytes</param>
/// <param name="signBytes">signature bytes</param>
/// <param name="abiNames">abi contract names to get abi information from</param>
/// <returns>List of signatures per required keys</returns>
public async Task<IEnumerable<string>> Sign(string chainId, List<string> requiredKeys, byte[] signBytes)
{
var result = await HttpHelper.PostJsonAsync<SecretSignResponse>("https://supersecretserver.com/sign", new SecretRequest {
chainId = chainId,
RequiredKeys = requiredKeys,
Data = signBytes
});
return result.Signatures;
}
}
// create new Eos client instance using your custom signature provider
Eos eos = new Eos(new EosConfigurator()
{
SignProvider = new SuperSecretSignProvider(),
HttpEndpoint = "https://nodes.eos42.io", //Mainnet
ChainId = "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906"
});
Is also possible to combine multiple signature providers to complete all the signatures for a transaction
Example:
Eos eos = new Eos(new EosConfigurator()
{
HttpEndpoint = "https://nodes.eos42.io", //Mainnet
ChainId = "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906",
ExpireSeconds = 60,
SignProvider = new CombinedSignersProvider(new List<ISignProvider>() {
new SuperSecretSignProvider(),
new DefaultSignProvider("myprivatekey")
}),
});