├── .gitignore
├── EosSharp
├── EosSharp.Core
│ ├── Api
│ │ └── v1
│ │ │ ├── Definitions
│ │ │ ├── EosApiMethodDef.t4
│ │ │ ├── EosApiTypeDef.t4
│ │ │ └── EosApiUtils.t4
│ │ │ ├── EosApi.cs
│ │ │ ├── EosApi.tt
│ │ │ ├── EosTypes.cs
│ │ │ └── EosTypes.tt
│ ├── DataAttributes
│ │ └── AbiFieldTypeAttribute.cs
│ ├── EosBase.cs
│ ├── EosConfigurator.cs
│ ├── EosSharp.Core.csproj
│ ├── Exceptions
│ │ ├── ApiErrorException.cs
│ │ └── ApiException.cs
│ ├── Helpers
│ │ ├── CryptoHelper.cs
│ │ └── SerializationHelper.cs
│ ├── Interfaces
│ │ ├── IHttpHandler.cs
│ │ └── ISignProvider.cs
│ ├── Providers
│ │ ├── AbiSerializationProvider.cs
│ │ ├── CombinedSignersProvider.cs
│ │ └── DefaultSignProvider.cs
│ └── SignedTransaction.cs
├── EosSharp.UnitTests.Core
│ ├── ApiUnitTestCases.cs
│ ├── EosSharp.UnitTests.Core.csproj
│ ├── EosTestCasesDef.t4
│ ├── EosUnitTestCases.cs
│ └── SerializationUnitTestCases.cs
├── EosSharp.UnitTests.Unity3D
│ ├── ApiUnitTests.cs
│ ├── ApiUnitTests.tt
│ ├── EosSharp.UnitTests.Unity3D.csproj
│ ├── EosUnitTests.cs
│ ├── EosUnitTests.tt
│ ├── SerializationUnitTests.cs
│ ├── SerializationUnitTests.tt
│ ├── SignUnitTests.cs
│ ├── StressUnitTests.cs
│ ├── UnityTester
│ │ ├── Assets
│ │ │ ├── Plugins.meta
│ │ │ ├── Scenes.meta
│ │ │ ├── Scenes
│ │ │ │ ├── SampleScene.unity
│ │ │ │ ├── SampleScene.unity.meta
│ │ │ │ ├── Scripts.meta
│ │ │ │ └── Scripts
│ │ │ │ │ ├── UnitTestsScript.cs
│ │ │ │ │ └── UnitTestsScript.cs.meta
│ │ │ ├── gs_home_devs_streamlined.png
│ │ │ └── gs_home_devs_streamlined.png.meta
│ │ ├── Logs
│ │ │ └── Packages-Update.log
│ │ ├── Packages
│ │ │ └── manifest.json
│ │ └── ProjectSettings
│ │ │ ├── AudioManager.asset
│ │ │ ├── ClusterInputManager.asset
│ │ │ ├── DynamicsManager.asset
│ │ │ ├── EditorBuildSettings.asset
│ │ │ ├── EditorSettings.asset
│ │ │ ├── GraphicsSettings.asset
│ │ │ ├── InputManager.asset
│ │ │ ├── NavMeshAreas.asset
│ │ │ ├── NetworkManager.asset
│ │ │ ├── Physics2DSettings.asset
│ │ │ ├── PresetManager.asset
│ │ │ ├── ProjectSettings.asset
│ │ │ ├── ProjectVersion.txt
│ │ │ ├── QualitySettings.asset
│ │ │ ├── TagManager.asset
│ │ │ ├── TimeManager.asset
│ │ │ ├── UnityConnectSettings.asset
│ │ │ └── VFXManager.asset
│ └── app.config
├── EosSharp.UnitTests
│ ├── ApiUnitTests.cs
│ ├── ApiUnitTests.tt
│ ├── EosSharp.UnitTests.csproj
│ ├── EosUnitTests.cs
│ ├── EosUnitTests.tt
│ ├── MultisigUnitTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── SerializationUnitTests.cs
│ ├── SerializationUnitTests.tt
│ ├── SignUnitTests.cs
│ ├── StressUnitTests.cs
│ ├── app.config
│ └── packages.config
├── EosSharp.Unity3D
│ ├── Eos.cs
│ ├── EosSharp.Unity3D.csproj
│ ├── HttpHelper.cs
│ └── UnityWebRequestAwaiter.cs
├── EosSharp.sln
└── EosSharp
│ ├── Eos.cs
│ ├── EosSharp.csproj
│ └── HttpHelper.cs
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | /EosSharp/EosSharp/obj
6 | /EosSharp/EosSharp.UnitTests/obj
7 | /EosSharp/packages
8 | *.suo
9 | /EosSharp/EosSharp/bin
10 | /EosSharp/EosSharp.UnitTests/bin
11 | /EosSharp/.vs
12 | /EosSharp/EosSharp.Unity3D/obj
13 | /EosSharp/EosSharp.Unity3D/bin
14 | /EosSharp/EosSharp.Core/bin
15 | /EosSharp/EosSharp.Core/obj
16 | /EosSharp/EosSharp.UnitTests.Core/bin/Debug/netstandard2.0
17 | /EosSharp/EosSharp.UnitTests.Core/obj
18 | /EosSharp/EosSharp.UnitTests.Unity3D/bin/Debug/netstandard2.0
19 | /EosSharp/EosSharp.UnitTests.Unity3D/obj
20 | /EosSharp/EosSharp.UnitTests.Unity3D/UnityTester/Assets/Plugins
21 | /EosSharp/EosSharp.UnitTests.Unity3D/UnityTester/.vs/UnityTester/v15
22 | /EosSharp/EosSharp.UnitTests.Unity3D/UnityTester/obj/Debug
23 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Api/v1/Definitions/EosApiUtils.t4:
--------------------------------------------------------------------------------
1 | <#+
2 | public class Field
3 | {
4 | public string Name { get; set; }
5 | public string Type { get; set; }
6 | public string Default { get; set; }
7 | public string AbiFieldType { get; set; }
8 | }
9 |
10 | public class ApiType
11 | {
12 | public string Name { get; set; }
13 | public Field[] Fields { get; set; }
14 | }
15 |
16 | public class ApiMethod
17 | {
18 | public string Module { get; set; }
19 | public string Name { get; set; }
20 | public string ResponseGenericTypes { get; set; }
21 | public bool IsResponseCollection { get; set; }
22 | public bool IsCachable { get; set; }
23 | public Field[] Request { get; set; }
24 | public Field[] Response { get; set; }
25 | public Field[] GenericResponse { get; set; }
26 | }
27 |
28 | public string SnakeCaseToPascalCase(string s)
29 | {
30 | var result = s.ToLower().Replace("_", " ");
31 | TextInfo info = CultureInfo.CurrentCulture.TextInfo;
32 | result = info.ToTitleCase(result).Replace(" ", string.Empty);
33 | return result;
34 | }
35 |
36 | public string RenderFieldDefault(Field field) {
37 | if(string.IsNullOrWhiteSpace(field.Default))
38 | return ";";
39 |
40 | if(field.Type.ToLower() == "string") {
41 | return " = \"" + field.Default + "\";";
42 | }
43 | else {
44 | return " = " + field.Default + ";";
45 | }
46 | }
47 |
48 | public string EscapeKeyWords(string s) {
49 |
50 | switch(s) {
51 | case "base":
52 | return "@base";
53 | case "class":
54 | return "@class";
55 | case "new":
56 | return "@new";
57 | }
58 |
59 | return s;
60 | }
61 | #>
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Api/v1/EosApi.cs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | // Auto Generated, do not edit.
6 | using EosSharp.Core;
7 | using EosSharp.Core.Api.v1;
8 | using EosSharp.Core.Interfaces;
9 | using System.Collections.Generic;
10 | using System.Threading.Tasks;
11 |
12 | namespace EosSharp.Core.Api.v1
13 | {
14 |
15 | ///
16 | /// EosApi defines api methods to interface with a http handler
17 | ///
18 | public class EosApi
19 | {
20 | public EosConfigurator Config { get; set; }
21 | public IHttpHandler HttpHandler { get; set; }
22 |
23 | ///
24 | /// Eos Client api constructor.
25 | ///
26 | /// Configures client parameters
27 | /// Http handler implementation
28 | public EosApi(EosConfigurator config, IHttpHandler httpHandler)
29 | {
30 | Config = config;
31 | HttpHandler = httpHandler;
32 | }
33 |
34 | public async Task GetInfo()
35 | {
36 | var url = string.Format("{0}/v1/chain/get_info", Config.HttpEndpoint);
37 | return await HttpHandler.GetJsonAsync(url);
38 | }
39 | public async Task GetAccount(GetAccountRequest data)
40 | {
41 | var url = string.Format("{0}/v1/chain/get_account", Config.HttpEndpoint);
42 | return await HttpHandler.PostJsonAsync(url, data);
43 | }
44 | public async Task GetCode(GetCodeRequest data, bool reload = false)
45 | {
46 | var url = string.Format("{0}/v1/chain/get_code", Config.HttpEndpoint);
47 | return await HttpHandler.PostJsonWithCacheAsync(url, data, reload);
48 | }
49 | public async Task GetAbi(GetAbiRequest data, bool reload = false)
50 | {
51 | var url = string.Format("{0}/v1/chain/get_abi", Config.HttpEndpoint);
52 | return await HttpHandler.PostJsonWithCacheAsync(url, data, reload);
53 | }
54 | public async Task GetRawCodeAndAbi(GetRawCodeAndAbiRequest data, bool reload = false)
55 | {
56 | var url = string.Format("{0}/v1/chain/get_raw_code_and_abi", Config.HttpEndpoint);
57 | return await HttpHandler.PostJsonWithCacheAsync(url, data, reload);
58 | }
59 | public async Task GetRawAbi(GetRawAbiRequest data, bool reload = false)
60 | {
61 | var url = string.Format("{0}/v1/chain/get_raw_abi", Config.HttpEndpoint);
62 | return await HttpHandler.PostJsonWithCacheAsync(url, data, reload);
63 | }
64 | public async Task AbiJsonToBin(AbiJsonToBinRequest data)
65 | {
66 | var url = string.Format("{0}/v1/chain/abi_json_to_bin", Config.HttpEndpoint);
67 | return await HttpHandler.PostJsonAsync(url, data);
68 | }
69 | public async Task AbiBinToJson(AbiBinToJsonRequest data)
70 | {
71 | var url = string.Format("{0}/v1/chain/abi_bin_to_json", Config.HttpEndpoint);
72 | return await HttpHandler.PostJsonAsync(url, data);
73 | }
74 | public async Task GetRequiredKeys(GetRequiredKeysRequest data)
75 | {
76 | var url = string.Format("{0}/v1/chain/get_required_keys", Config.HttpEndpoint);
77 | return await HttpHandler.PostJsonAsync(url, data);
78 | }
79 | public async Task GetBlock(GetBlockRequest data)
80 | {
81 | var url = string.Format("{0}/v1/chain/get_block", Config.HttpEndpoint);
82 | return await HttpHandler.PostJsonAsync(url, data);
83 | }
84 | public async Task GetBlockHeaderState(GetBlockHeaderStateRequest data)
85 | {
86 | var url = string.Format("{0}/v1/chain/get_block_header_state", Config.HttpEndpoint);
87 | return await HttpHandler.PostJsonAsync(url, data);
88 | }
89 | public async Task> GetTableRows(GetTableRowsRequest data)
90 | {
91 | var url = string.Format("{0}/v1/chain/get_table_rows", Config.HttpEndpoint);
92 | return await HttpHandler.PostJsonAsync>(url, data);
93 | }
94 | public async Task GetTableRows(GetTableRowsRequest data)
95 | {
96 | var url = string.Format("{0}/v1/chain/get_table_rows", Config.HttpEndpoint);
97 | return await HttpHandler.PostJsonAsync(url, data);
98 | }
99 | public async Task GetTableByScope(GetTableByScopeRequest data)
100 | {
101 | var url = string.Format("{0}/v1/chain/get_table_by_scope", Config.HttpEndpoint);
102 | return await HttpHandler.PostJsonAsync(url, data);
103 | }
104 | public async Task GetCurrencyBalance(GetCurrencyBalanceRequest data)
105 | {
106 | var url = string.Format("{0}/v1/chain/get_currency_balance", Config.HttpEndpoint);
107 | return new GetCurrencyBalanceResponse() { assets = await HttpHandler.PostJsonAsync>(url, data) };
108 | }
109 | public async Task GetCurrencyStats(GetCurrencyStatsRequest data)
110 | {
111 | var url = string.Format("{0}/v1/chain/get_currency_stats", Config.HttpEndpoint);
112 | return new GetCurrencyStatsResponse() { stats = await HttpHandler.PostJsonAsync>(url, data) };
113 | }
114 | public async Task GetProducers(GetProducersRequest data)
115 | {
116 | var url = string.Format("{0}/v1/chain/get_producers", Config.HttpEndpoint);
117 | return await HttpHandler.PostJsonAsync(url, data);
118 | }
119 | public async Task GetProducerSchedule()
120 | {
121 | var url = string.Format("{0}/v1/chain/get_producer_schedule", Config.HttpEndpoint);
122 | return await HttpHandler.GetJsonAsync(url);
123 | }
124 | public async Task GetScheduledTransactions(GetScheduledTransactionsRequest data)
125 | {
126 | var url = string.Format("{0}/v1/chain/get_scheduled_transactions", Config.HttpEndpoint);
127 | return await HttpHandler.PostJsonAsync(url, data);
128 | }
129 | public async Task PushTransaction(PushTransactionRequest data)
130 | {
131 | var url = string.Format("{0}/v1/chain/push_transaction", Config.HttpEndpoint);
132 | return await HttpHandler.PostJsonAsync(url, data);
133 | }
134 | public async Task GetActions(GetActionsRequest data)
135 | {
136 | var url = string.Format("{0}/v1/history/get_actions", Config.HttpEndpoint);
137 | return await HttpHandler.PostJsonAsync(url, data);
138 | }
139 | public async Task GetTransaction(GetTransactionRequest data)
140 | {
141 | var url = string.Format("{0}/v1/history/get_transaction", Config.HttpEndpoint);
142 | return await HttpHandler.PostJsonAsync(url, data);
143 | }
144 | public async Task GetKeyAccounts(GetKeyAccountsRequest data)
145 | {
146 | var url = string.Format("{0}/v1/history/get_key_accounts", Config.HttpEndpoint);
147 | return await HttpHandler.PostJsonAsync(url, data);
148 | }
149 | public async Task GetControlledAccounts(GetControlledAccountsRequest data)
150 | {
151 | var url = string.Format("{0}/v1/history/get_controlled_accounts", Config.HttpEndpoint);
152 | return await HttpHandler.PostJsonAsync(url, data);
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Api/v1/EosApi.tt:
--------------------------------------------------------------------------------
1 | <#@ template debug="false" hostspecific="false" language="C#" #>
2 | <#@ assembly name="System.Core" #>
3 | <#@ import namespace="System.Globalization" #>
4 | <#@ include file=".\..\..\..\EosSharp.Core\Api\v1\Definitions\EosApiTypeDef.t4" #>
5 | <#@ include file=".\..\..\..\EosSharp.Core\Api\v1\Definitions\EosApiMethodDef.t4" #>
6 | <#@ output extension=".cs" #>
7 | // Auto Generated, do not edit.
8 | using EosSharp.Core;
9 | using EosSharp.Core.Api.v1;
10 | using EosSharp.Core.Interfaces;
11 | using System.Collections.Generic;
12 | using System.Threading.Tasks;
13 |
14 | namespace EosSharp.Core.Api.v1
15 | {
16 |
17 | ///
18 | /// EosApi defines api methods to interface with a http handler
19 | ///
20 | public class EosApi
21 | {
22 | public EosConfigurator Config { get; set; }
23 | public IHttpHandler HttpHandler { get; set; }
24 |
25 | ///
26 | /// Eos Client api constructor.
27 | ///
28 | /// Configures client parameters
29 | /// Http handler implementation
30 | public EosApi(EosConfigurator config, IHttpHandler httpHandler)
31 | {
32 | Config = config;
33 | HttpHandler = httpHandler;
34 | }
35 |
36 | <# foreach (var method in apiMethods) { #>
37 | <# if(method.Request == null) { #>
38 | <# if(!string.IsNullOrWhiteSpace(method.ResponseGenericTypes)) {#>
39 | public async Task<<#= SnakeCaseToPascalCase(method.Name) #>Response<#= method.ResponseGenericTypes #>> <#= SnakeCaseToPascalCase(method.Name) #><#= method.ResponseGenericTypes #>()
40 | {
41 | var url = string.Format("{0}/v1/<#= method.Module #>/<#= method.Name #>", Config.HttpEndpoint);
42 | <# if(method.IsResponseCollection) { #>
43 | return new <#= SnakeCaseToPascalCase(method.Name) #>Response() { <#= EscapeKeyWords(method.Response[0].Name) #> = await HttpHandler.GetJsonAsync<<#= method.Response[0].Type#>>(url) };
44 | <# } else { #>
45 | return await HttpHandler.GetJsonAsync<<#= SnakeCaseToPascalCase(method.Name) #>Response<#= method.ResponseGenericTypes #>>(url);
46 | <# } #>
47 | }
48 | <# } #>
49 | public async Task<<#= SnakeCaseToPascalCase(method.Name) #>Response> <#= SnakeCaseToPascalCase(method.Name) #>()
50 | {
51 | var url = string.Format("{0}/v1/<#= method.Module #>/<#= method.Name #>", Config.HttpEndpoint);
52 | <# if(method.IsResponseCollection) { #>
53 | return new <#= SnakeCaseToPascalCase(method.Name) #>Response() { <#= EscapeKeyWords(method.Response[0].Name) #> = await HttpHandler.GetJsonAsync<<#= method.Response[0].Type#>>(url) };
54 | <# } else { #>
55 | return await HttpHandler.GetJsonAsync<<#= SnakeCaseToPascalCase(method.Name) #>Response>(url);
56 | <# } #>
57 | }
58 | <# } else { #>
59 | <# if(!string.IsNullOrWhiteSpace(method.ResponseGenericTypes)) {#>
60 | public async Task<<#= SnakeCaseToPascalCase(method.Name) #>Response<#= method.ResponseGenericTypes #>> <#= SnakeCaseToPascalCase(method.Name) #><#= method.ResponseGenericTypes #>(<#= SnakeCaseToPascalCase(method.Name) #>Request data<#= method.IsCachable ? ", bool reload = false" : "" #>)
61 | {
62 | var url = string.Format("{0}/v1/<#= method.Module #>/<#= method.Name #>", Config.HttpEndpoint);
63 | <# if(method.IsResponseCollection) { #>
64 | return new <#= SnakeCaseToPascalCase(method.Name) #>Response() { <#= EscapeKeyWords(method.Response[0].Name) #> = await httpHandler.PostJson<#= method.IsCachable ? "WithCache" : "" #>Async<<#= method.Response[0].Type#>>(url, data<#= method.IsCachable ? ", reload" : "" #>) };
65 | <# } else { #>
66 | return await HttpHandler.PostJson<#= method.IsCachable ? "WithCache" : "" #>Async<<#= SnakeCaseToPascalCase(method.Name) #>Response<#= method.ResponseGenericTypes #>>(url, data<#= method.IsCachable ? ", reload" : "" #>);
67 | <# } #>
68 | }
69 | <# } #>
70 | public async Task<<#= SnakeCaseToPascalCase(method.Name) #>Response> <#= SnakeCaseToPascalCase(method.Name) #>(<#= SnakeCaseToPascalCase(method.Name) #>Request data<#= method.IsCachable ? ", bool reload = false" : "" #>)
71 | {
72 | var url = string.Format("{0}/v1/<#= method.Module #>/<#= method.Name #>", Config.HttpEndpoint);
73 | <# if(method.IsResponseCollection) { #>
74 | return new <#= SnakeCaseToPascalCase(method.Name) #>Response() { <#= EscapeKeyWords(method.Response[0].Name) #> = await HttpHandler.PostJson<#= method.IsCachable ? "WithCache" : "" #>Async<<#= method.Response[0].Type#>>(url, data<#= method.IsCachable ? ", reload" : "" #>) };
75 | <# } else { #>
76 | return await HttpHandler.PostJson<#= method.IsCachable ? "WithCache" : "" #>Async<<#= SnakeCaseToPascalCase(method.Name) #>Response>(url, data<#= method.IsCachable ? ", reload" : "" #>);
77 | <# } #>
78 | }
79 | <# } #>
80 | <# } #>
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Api/v1/EosTypes.tt:
--------------------------------------------------------------------------------
1 | <#@ template debug="false" hostspecific="false" language="C#" #>
2 | <#@ assembly name="System.Core" #>
3 | <#@ import namespace="System.Globalization" #>
4 | <#@ include file=".\Definitions\EosApiTypeDef.t4" #>
5 | <#@ include file=".\Definitions\EosApiMethodDef.t4" #>
6 | <#@ output extension=".cs" #>
7 | // Auto Generated, do not edit.
8 | using EosSharp.Core.DataAttributes;
9 | using System;
10 | using System.Collections.Generic;
11 |
12 | namespace EosSharp.Core.Api.v1
13 | {
14 | #region generate api types
15 | <# foreach (var type in apiTypes) { #>
16 | [Serializable]
17 | public class <#= type.Name #>
18 | {
19 | <# foreach (var field in type.Fields) { #>
20 | <#= !string.IsNullOrWhiteSpace(field.AbiFieldType) ? "[AbiFieldType(\""+ field.AbiFieldType +"\")]" : "" #>
21 | public <#= field.Type #> <#= EscapeKeyWords(field.Name) #><#= RenderFieldDefault(field) #>
22 | <# } #>
23 | }
24 | <# } #>
25 | #endregion
26 |
27 | #region generate api method types
28 | <# foreach (var method in apiMethods) { #>
29 | <# if (method.Request != null) { #>
30 | [Serializable]
31 | public class <#= SnakeCaseToPascalCase(method.Name) #>Request
32 | {
33 | <# foreach (var field in method.Request) { #>
34 | public <#= field.Type #> <#= EscapeKeyWords(field.Name) #><#= RenderFieldDefault(field) #>
35 | <# } #>
36 | }
37 | <# } #>
38 | <# if (method.Response != null) { #>
39 | [Serializable]
40 | public class <#= SnakeCaseToPascalCase(method.Name) #>Response
41 | {
42 | <# foreach (var field in method.Response) { #>
43 | public <#= field.Type #> <#= EscapeKeyWords(field.Name) #><#= RenderFieldDefault(field) #>
44 | <# } #>
45 | }
46 | <# } #>
47 | <# if (method.GenericResponse != null && !string.IsNullOrWhiteSpace(method.ResponseGenericTypes)) { #>
48 | [Serializable]
49 | public class <#= SnakeCaseToPascalCase(method.Name) #>Response<#= method.ResponseGenericTypes #>
50 | {
51 | <# foreach (var field in method.GenericResponse) { #>
52 | public <#= field.Type #> <#= EscapeKeyWords(field.Name) #><#= RenderFieldDefault(field) #>
53 | <# } #>
54 | }
55 | <# } #>
56 | <# } #>
57 | #endregion
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/DataAttributes/AbiFieldTypeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EosSharp.Core.DataAttributes
4 | {
5 | ///
6 | /// Data Attribute to map how the field is represented in the abi
7 | ///
8 | public class AbiFieldTypeAttribute : Attribute
9 | {
10 | public string AbiType { get; set; }
11 |
12 | public AbiFieldTypeAttribute(string abiType)
13 | {
14 | AbiType = abiType;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/EosConfigurator.cs:
--------------------------------------------------------------------------------
1 | using EosSharp.Core.Interfaces;
2 | using System;
3 |
4 | namespace EosSharp.Core
5 | {
6 | ///
7 | /// Aggregates all properties to configure Eos client
8 | ///
9 | public class EosConfigurator
10 | {
11 | ///
12 | /// http or https location of a nodeosd server providing a chain API.
13 | ///
14 | public string HttpEndpoint { get; set; } = "http://127.0.0.1:8888";
15 | ///
16 | /// unique ID for the blockchain you're connecting to. If no ChainId is provided it will get from the get_info API call.
17 | ///
18 | public string ChainId { get; set; }
19 | ///
20 | /// number of seconds before the transaction will expire. The time is based on the nodeosd's clock.
21 | /// An unexpired transaction that may have had an error is a liability until the expiration is reached, this time should be brief.
22 | ///
23 | public double ExpireSeconds { get; set; } = 60;
24 |
25 | ///
26 | /// How many blocks behind to use for TAPoS reference block
27 | ///
28 | public UInt32 blocksBehind { get; set; } = 3;
29 | ///
30 | /// signature implementation to handle available keys and signing transactions. Use the DefaultSignProvider with a privateKey to sign transactions inside the lib.
31 | ///
32 | public ISignProvider SignProvider { get; set; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/EosSharp.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | EosApi.tt
14 | True
15 | True
16 |
17 |
18 | EosTypes.tt
19 | True
20 | True
21 |
22 |
23 |
24 |
25 |
26 | EosApi.cs
27 | TextTemplatingFileGenerator
28 |
29 |
30 | EosTypes.cs
31 | TextTemplatingFileGenerator
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Exceptions/ApiErrorException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 |
5 | namespace EosSharp.Core.Exceptions
6 | {
7 | ///
8 | /// Wrapper exception for EOSIO api error
9 | ///
10 | [Serializable]
11 | public class ApiErrorException : Exception
12 | {
13 | public int code;
14 | public string message;
15 | public ApiError error;
16 |
17 | public ApiErrorException()
18 | {
19 |
20 | }
21 |
22 | public ApiErrorException(SerializationInfo info, StreamingContext context)
23 | {
24 | if (info == null)
25 | return;
26 |
27 | code = info.GetInt32("code");
28 | message = info.GetString("message");
29 | error = (ApiError)info.GetValue("error", typeof(ApiError));
30 | }
31 |
32 | public override void GetObjectData(SerializationInfo info, StreamingContext context)
33 | {
34 | if (info == null)
35 | return;
36 |
37 | base.GetObjectData(info, context);
38 | info.AddValue("code", code);
39 | info.AddValue("message", message);
40 | info.AddValue("error", error);
41 | }
42 | }
43 |
44 | ///
45 | /// EOSIO Api Error
46 | ///
47 | [Serializable]
48 | public class ApiError
49 | {
50 | public int code;
51 | public string name;
52 | public string what;
53 | public List details;
54 | }
55 |
56 | ///
57 | /// EOSIO Api Error detail
58 | ///
59 | [Serializable]
60 | public class ApiErrorDetail
61 | {
62 | public string message;
63 | public string file;
64 | public int line_number;
65 | public string method;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Exceptions/ApiException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace EosSharp.Core.Exceptions
5 | {
6 | ///
7 | /// Generic Api exception
8 | ///
9 | [Serializable]
10 | public class ApiException : Exception
11 | {
12 | public int StatusCode { get; set; }
13 | public string Content { get; set; }
14 |
15 | public ApiException()
16 | {
17 |
18 | }
19 |
20 | public ApiException(SerializationInfo info, StreamingContext context)
21 | {
22 | if (info == null)
23 | return;
24 |
25 | StatusCode = info.GetInt32("StatusCode");
26 | Content = info.GetString("Content");
27 | }
28 |
29 | public override void GetObjectData(SerializationInfo info, StreamingContext context)
30 | {
31 | if (info == null)
32 | return;
33 |
34 | base.GetObjectData(info, context);
35 | info.AddValue("StatusCode", StatusCode);
36 | info.AddValue("Content", Content);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Interfaces/IHttpHandler.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Net.Http;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace EosSharp.Core.Interfaces
7 | {
8 | ///
9 | /// Http handler interface for cross platform specific implementations
10 | ///
11 | public interface IHttpHandler
12 | {
13 | ///
14 | /// Clear cached responses from requests called with Post/GetWithCacheAsync
15 | ///
16 | void ClearResponseCache();
17 |
18 | ///
19 | /// Make post request with data converted to json asynchronously
20 | ///
21 | /// Response type
22 | /// Url to send the request
23 | /// data sent in the body
24 | /// Response data deserialized to type TResponseData
25 | Task PostJsonAsync(string url, object data);
26 |
27 | ///
28 | /// Make post request with data converted to json asynchronously
29 | ///
30 | /// Response type
31 | /// Url to send the request
32 | /// data sent in the body
33 | /// Notification that operation should be canceled
34 | /// Response data deserialized to type TResponseData
35 | Task PostJsonAsync(string url, object data, CancellationToken cancellationToken);
36 |
37 | ///
38 | /// Make post request with data converted to json asynchronously.
39 | /// Response is cached based on input (url, data)
40 | ///
41 | /// Response type
42 | /// Url to send the request
43 | /// data sent in the body
44 | /// ignore cached value and make a request caching the result
45 | /// Response data deserialized to type TResponseData
46 | Task PostJsonWithCacheAsync(string url, object data, bool reload = false);
47 |
48 | ///
49 | /// Make post request with data converted to json asynchronously.
50 | /// Response is cached based on input (url, data)
51 | ///
52 | /// Response type
53 | /// Url to send the request
54 | /// data sent in the body
55 | /// Notification that operation should be canceled
56 | /// ignore cached value and make a request caching the result
57 | /// Response data deserialized to type TResponseData
58 | Task PostJsonWithCacheAsync(string url, object data, CancellationToken cancellationToken, bool reload = false);
59 |
60 | ///
61 | /// Make get request asynchronously.
62 | ///
63 | /// Response type
64 | /// Url to send the request
65 | /// Response data deserialized to type TResponseData
66 | Task GetJsonAsync(string url);
67 |
68 | ///
69 | /// Make get request asynchronously.
70 | ///
71 | /// Response type
72 | /// Url to send the request
73 | /// Notification that operation should be canceled
74 | /// Response data deserialized to type TResponseData
75 | Task GetJsonAsync(string url, CancellationToken cancellationToken);
76 |
77 | ///
78 | /// Generic http request sent asynchronously
79 | ///
80 | /// request body
81 | /// Stream with response
82 | Task SendAsync(HttpRequestMessage request);
83 |
84 | ///
85 | /// Generic http request sent asynchronously
86 | ///
87 | /// request body
88 | /// /// Notification that operation should be canceled
89 | /// Stream with response
90 | Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
91 |
92 | ///
93 | /// Upsert response data in the data store
94 | ///
95 | /// response data type
96 | /// data key
97 | /// response data
98 | void UpdateResponseDataCache(string hashKey, TResponseData responseData);
99 |
100 | ///
101 | /// Calculate request unique hash key
102 | ///
103 | /// Url to send the request
104 | /// data sent in the body
105 | ///
106 | string GetRequestHashKey(string url, object data);
107 |
108 | ///
109 | /// Convert response to stream
110 | ///
111 | /// response object
112 | /// Stream with response
113 | Task BuildSendResponse(HttpResponseMessage response);
114 |
115 | ///
116 | /// Convert stream to a string
117 | ///
118 | ///
119 | ///
120 | Task StreamToStringAsync(Stream stream);
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Interfaces/ISignProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 |
4 | namespace EosSharp.Core.Interfaces
5 | {
6 | ///
7 | /// Signature provider Interface to delegate multiple signing implementations
8 | ///
9 | public interface ISignProvider
10 | {
11 | ///
12 | /// Get available public keys from signature provider
13 | ///
14 | /// List of public keys
15 | Task> GetAvailableKeys();
16 |
17 | ///
18 | /// Sign bytes using the signature provider
19 | ///
20 | /// EOSIO Chain id
21 | /// required public keys for signing this bytes
22 | /// signature bytes
23 | /// abi contract names to get abi information from
24 | /// List of signatures per required keys
25 | Task> Sign(string chainId, IEnumerable requiredKeys, byte[] signBytes, IEnumerable abiNames = null);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Providers/CombinedSignersProvider.cs:
--------------------------------------------------------------------------------
1 | using EosSharp.Core.Interfaces;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Linq;
7 |
8 | namespace EosSharp.Core.Providers
9 | {
10 | ///
11 | /// Signature provider that combine multiple signature providers to complete all the signatures for a transaction
12 | ///
13 | public class CombinedSignersProvider : ISignProvider
14 | {
15 | private List Signers { get; set; }
16 |
17 | ///
18 | /// Creates the provider with a list of signature providers
19 | ///
20 | ///
21 | public CombinedSignersProvider(List signers)
22 | {
23 | if (signers == null || signers.Count == 0)
24 | throw new ArgumentNullException("Required atleast one signer.");
25 |
26 | Signers = signers;
27 | }
28 |
29 | ///
30 | /// Get available public keys from the list of signature providers
31 | ///
32 | /// List of public keys
33 | public async Task> GetAvailableKeys()
34 | {
35 | var availableKeysListTasks = Signers.Select(s => s.GetAvailableKeys());
36 | var availableKeysList = await Task.WhenAll(availableKeysListTasks);
37 | return availableKeysList.SelectMany(k => k).Distinct();
38 | }
39 |
40 | ///
41 | /// Sign bytes using the list of signature providers
42 | ///
43 | /// EOSIO Chain id
44 | /// required public keys for signing this bytes
45 | /// signature bytes
46 | /// abi contract names to get abi information from
47 | /// List of signatures per required keys
48 | public async Task> Sign(string chainId, IEnumerable requiredKeys, byte[] signBytes, IEnumerable abiNames = null)
49 | {
50 | var signatureTasks = Signers.Select(s => s.Sign(chainId, requiredKeys, signBytes, abiNames));
51 | var signatures = await Task.WhenAll(signatureTasks);
52 | return signatures.SelectMany(k => k).Distinct();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/Providers/DefaultSignProvider.cs:
--------------------------------------------------------------------------------
1 | using Cryptography.ECDSA;
2 | using EosSharp.Core.Helpers;
3 | using EosSharp.Core.Interfaces;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace EosSharp.Core.Providers
11 | {
12 | ///
13 | /// Signature provider default implementation that stores private keys in memory
14 | ///
15 | public class DefaultSignProvider : ISignProvider
16 | {
17 | private readonly byte[] KeyTypeBytes = Encoding.UTF8.GetBytes("K1");
18 | private readonly Dictionary Keys = new Dictionary();
19 |
20 | ///
21 | /// Create provider with single private key
22 | ///
23 | ///
24 | public DefaultSignProvider(string privateKey)
25 | {
26 | var privKeyBytes = CryptoHelper.GetPrivateKeyBytesWithoutCheckSum(privateKey);
27 | var pubKey = CryptoHelper.PubKeyBytesToString(Secp256K1Manager.GetPublicKey(privKeyBytes, true));
28 | Keys.Add(pubKey, privKeyBytes);
29 | }
30 |
31 | ///
32 | /// Create provider with list of private keys
33 | ///
34 | ///
35 | public DefaultSignProvider(List privateKeys)
36 | {
37 | if (privateKeys == null || privateKeys.Count == 0)
38 | throw new ArgumentNullException("privateKeys");
39 |
40 | foreach(var key in privateKeys)
41 | {
42 | var privKeyBytes = CryptoHelper.GetPrivateKeyBytesWithoutCheckSum(key);
43 | var pubKey = CryptoHelper.PubKeyBytesToString(Secp256K1Manager.GetPublicKey(privKeyBytes, true));
44 | Keys.Add(pubKey, privKeyBytes);
45 | }
46 | }
47 |
48 | ///
49 | /// Create provider with dictionary of encoded key pairs
50 | ///
51 | ///
52 | public DefaultSignProvider(Dictionary encodedKeys)
53 | {
54 | if (encodedKeys == null || encodedKeys.Count == 0)
55 | throw new ArgumentNullException("encodedKeys");
56 |
57 | foreach (var keyPair in encodedKeys)
58 | {
59 | var privKeyBytes = CryptoHelper.GetPrivateKeyBytesWithoutCheckSum(keyPair.Value);
60 | Keys.Add(keyPair.Key, privKeyBytes);
61 | }
62 | }
63 |
64 | ///
65 | /// Create provider with dictionary of key pair with private key as byte array
66 | ///
67 | ///
68 | public DefaultSignProvider(Dictionary keys)
69 | {
70 | if (keys == null || keys.Count == 0)
71 | throw new ArgumentNullException("encodedKeys");
72 |
73 | Keys = keys;
74 | }
75 |
76 | ///
77 | /// Get available public keys from signature provider
78 | ///
79 | /// List of public keys
80 | public Task> GetAvailableKeys()
81 | {
82 | return Task.FromResult(Keys.Keys.AsEnumerable());
83 | }
84 |
85 | ///
86 | /// Sign bytes using the signature provider
87 | ///
88 | /// EOSIO Chain id
89 | /// required public keys for signing this bytes
90 | /// signature bytes
91 | /// abi contract names to get abi information from
92 | /// List of signatures per required keys
93 | public Task> Sign(string chainId, IEnumerable requiredKeys, byte[] signBytes, IEnumerable abiNames = null)
94 | {
95 | if (requiredKeys == null)
96 | return Task.FromResult(new List().AsEnumerable());
97 |
98 | var availableAndReqKeys = requiredKeys.Intersect(Keys.Keys);
99 |
100 | var data = new List()
101 | {
102 | Hex.HexToBytes(chainId),
103 | signBytes,
104 | new byte[32]
105 | };
106 |
107 | var hash = Sha256Manager.GetHash(SerializationHelper.Combine(data));
108 |
109 | return Task.FromResult(availableAndReqKeys.Select(key =>
110 | {
111 | var sign = Secp256K1Manager.SignCompressedCompact(hash, Keys[key]);
112 | var check = new List() { sign, KeyTypeBytes };
113 | var checksum = Ripemd160Manager.GetHash(SerializationHelper.Combine(check)).Take(4).ToArray();
114 | var signAndChecksum = new List() { sign, checksum };
115 |
116 | return "SIG_K1_" + Base58.Encode(SerializationHelper.Combine(signAndChecksum));
117 | }));
118 | }
119 | }
120 | }
--------------------------------------------------------------------------------
/EosSharp/EosSharp.Core/SignedTransaction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace EosSharp.Core
6 | {
7 | public class SignedTransaction
8 | {
9 | public IEnumerable Signatures { get; set; }
10 | public byte[] PackedTransaction { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.UnitTests.Core/ApiUnitTestCases.cs:
--------------------------------------------------------------------------------
1 | using EosSharp.Core;
2 | using EosSharp.Core.Api.v1;
3 | using EosSharp.Core.Helpers;
4 | using EosSharp.Core.Providers;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace EosSharp.UnitTests
11 | {
12 | public class ApiUnitTestCases
13 | {
14 | private EosConfigurator EosConfig;
15 | private EosApi DefaultApi;
16 |
17 | public ApiUnitTestCases(EosConfigurator eosConfig, EosApi api)
18 | {
19 | EosConfig = eosConfig;
20 | DefaultApi = api;
21 | }
22 |
23 | public Task GetInfo()
24 | {
25 | return DefaultApi.GetInfo();
26 | }
27 |
28 | public Task GetAccount()
29 | {
30 | return DefaultApi.GetAccount(new GetAccountRequest()
31 | {
32 | account_name = "eosio"
33 | });
34 | }
35 |
36 | public Task GetCode()
37 | {
38 | return DefaultApi.GetCode(new GetCodeRequest()
39 | {
40 | account_name = "eosio.token",
41 | code_as_wasm = true
42 | });
43 | }
44 |
45 | public Task GetAbi()
46 | {
47 | return DefaultApi.GetAbi(new GetAbiRequest()
48 | {
49 | account_name = "eosio.token"
50 | });
51 | }
52 |
53 | public async Task GetRawCodeAndAbi()
54 | {
55 | var result = await DefaultApi.GetRawCodeAndAbi(new GetRawCodeAndAbiRequest()
56 | {
57 | account_name = "eosio.token"
58 | });
59 |
60 | var abiSerializer = new AbiSerializationProvider(DefaultApi);
61 | var abiObject = abiSerializer.DeserializePackedAbi(result.abi);
62 | }
63 |
64 | public async Task GetRawAbi()
65 | {
66 | var result = await DefaultApi.GetRawAbi(new GetRawAbiRequest()
67 | {
68 | account_name = "eosio.token"
69 | });
70 |
71 | var abiSerializer = new AbiSerializationProvider(DefaultApi);
72 | var abiObject = abiSerializer.DeserializePackedAbi(result.abi);
73 | }
74 |
75 | public Task AbiJsonToBin()
76 | {
77 | return DefaultApi.AbiJsonToBin(new AbiJsonToBinRequest() {
78 | code = "eosio.token",
79 | action = "transfer",
80 | args = new Dictionary() {
81 | { "from", "eosio" },
82 | { "to", "eosio.names" },
83 | { "quantity", "1.0000 EOS" },
84 | { "memo", "hello crypto world!" }
85 | }
86 | });
87 | }
88 |
89 | public async Task AbiBinToJson()
90 | {
91 | var binArgsResult = await DefaultApi.AbiJsonToBin(new AbiJsonToBinRequest()
92 | {
93 | code = "eosio.token",
94 | action = "transfer",
95 | args = new Dictionary() {
96 | { "from", "eosio" },
97 | { "to", "eosio.names" },
98 | { "quantity", "1.0000 EOS" },
99 | { "memo", "hello crypto world!" }
100 | }
101 | });
102 |
103 | await DefaultApi.AbiBinToJson(new AbiBinToJsonRequest()
104 | {
105 | code = "eosio.token",
106 | action = "transfer",
107 | binargs = binArgsResult.binargs
108 | });
109 | }
110 |
111 | public async Task GetRequiredKeys()
112 | {
113 | var getInfoResult = await DefaultApi.GetInfo();
114 | var getBlockResult = await DefaultApi.GetBlock(new GetBlockRequest()
115 | {
116 | block_num_or_id = getInfoResult.last_irreversible_block_num.ToString()
117 | });
118 |
119 | var trx = new Transaction()
120 | {
121 | //trx headers
122 | expiration = getInfoResult.head_block_time.AddSeconds(60), //expire Seconds
123 | ref_block_num = (UInt16)(getInfoResult.last_irreversible_block_num & 0xFFFF),
124 | ref_block_prefix = getBlockResult.ref_block_prefix,
125 | // trx info
126 | max_net_usage_words = 0,
127 | max_cpu_usage_ms = 0,
128 | delay_sec = 0,
129 | context_free_actions = new List(),
130 | actions = new List()
131 | {
132 | new Core.Api.v1.Action()
133 | {
134 | account = "eosio.token",
135 | authorization = new List()
136 | {
137 | new PermissionLevel() {actor = "tester112345", permission = "active" }
138 | },
139 | name = "transfer",
140 | data = new Dictionary() {
141 | { "from", "tester112345" },
142 | { "to", "tester212345" },
143 | { "quantity", "1.0000 EOS" },
144 | { "memo", "hello crypto world!" }
145 | }
146 | }
147 | },
148 | transaction_extensions = new List()
149 | };
150 |
151 | int actionIndex = 0;
152 | var abiSerializer = new AbiSerializationProvider(DefaultApi);
153 | var abiResponses = await abiSerializer.GetTransactionAbis(trx);
154 |
155 | foreach (var action in trx.context_free_actions)
156 | {
157 | action.data = SerializationHelper.ByteArrayToHexString(abiSerializer.SerializeActionData(action, abiResponses[actionIndex++]));
158 | }
159 |
160 | foreach (var action in trx.actions)
161 | {
162 | action.data = SerializationHelper.ByteArrayToHexString(abiSerializer.SerializeActionData(action, abiResponses[actionIndex++]));
163 | }
164 |
165 | var getRequiredResult = await DefaultApi.GetRequiredKeys(new GetRequiredKeysRequest()
166 | {
167 | available_keys = new List() { "EOS8Q8CJqwnSsV4A6HDBEqmQCqpQcBnhGME1RUvydDRnswNngpqfr" },
168 | transaction = trx
169 | });
170 | }
171 |
172 | public async Task GetBlock()
173 | {
174 | var getInfoResult = await DefaultApi.GetInfo();
175 | var getBlockResult = await DefaultApi.GetBlock(new GetBlockRequest()
176 | {
177 | block_num_or_id = getInfoResult.last_irreversible_block_num.ToString()
178 | });
179 | }
180 |
181 | public async Task GetBlockHeaderState()
182 | {
183 | var getInfoResult = await DefaultApi.GetInfo();
184 | var result = await DefaultApi.GetBlockHeaderState(new GetBlockHeaderStateRequest()
185 | {
186 | block_num_or_id = getInfoResult.head_block_num.ToString()
187 | });
188 | }
189 |
190 | public Task GetTableRows()
191 | {
192 | return DefaultApi.GetTableRows(new GetTableRowsRequest()
193 | {
194 | json = true,
195 | code = "eosio.token",
196 | scope = "EOS",
197 | table = "stat"
198 | });
199 | }
200 |
201 | public Task GetTableByScope()
202 | {
203 | return DefaultApi.GetTableByScope(new GetTableByScopeRequest()
204 | {
205 | code = "eosio.token",
206 | table = "accounts"
207 | });
208 | }
209 |
210 | public Task GetCurrencyBalance()
211 | {
212 | return DefaultApi.GetCurrencyBalance(new GetCurrencyBalanceRequest()
213 | {
214 | code = "eosio.token",
215 | account = "tester112345",
216 | symbol = "EOS"
217 | });
218 | }
219 |
220 | public Task GetCurrencyStats()
221 | {
222 | return DefaultApi.GetCurrencyStats(new GetCurrencyStatsRequest()
223 | {
224 | code = "eosio.token",
225 | symbol = "EOS"
226 | });
227 | }
228 |
229 | public Task GetProducers()
230 | {
231 | return DefaultApi.GetProducers(new GetProducersRequest()
232 | {
233 | json = false,
234 | });
235 | }
236 |
237 | public Task GetProducerSchedule()
238 | {
239 | return DefaultApi.GetProducerSchedule();
240 | }
241 |
242 | public Task GetScheduledTransactions()
243 | {
244 | return DefaultApi.GetScheduledTransactions(new GetScheduledTransactionsRequest() {
245 | json = true
246 | });
247 | }
248 |
249 | public Task PushTransaction()
250 | {
251 | return CreateTransaction();
252 | }
253 |
254 | public Task GetActions()
255 | {
256 | return DefaultApi.GetActions(new GetActionsRequest() {
257 | account_name = "eosio"
258 | });
259 | }
260 |
261 | public async Task GetTransaction()
262 | {
263 | var trxResult = await CreateTransaction();
264 |
265 | var result = await DefaultApi.GetTransaction(new GetTransactionRequest()
266 | {
267 | id = trxResult.transaction_id
268 | });
269 | }
270 |
271 | public Task GetKeyAccounts()
272 | {
273 | return DefaultApi.GetKeyAccounts(new GetKeyAccountsRequest()
274 | {
275 | public_key = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
276 | });
277 | }
278 |
279 | public Task GetControlledAccounts()
280 | {
281 | return DefaultApi.GetControlledAccounts(new GetControlledAccountsRequest()
282 | {
283 | controlling_account = "eosio"
284 | });
285 | }
286 |
287 | private async Task CreateTransaction()
288 | {
289 | var getInfoResult = await DefaultApi.GetInfo();
290 | var getBlockResult = await DefaultApi.GetBlock(new GetBlockRequest()
291 | {
292 | block_num_or_id = getInfoResult.last_irreversible_block_num.ToString()
293 | });
294 |
295 |
296 | var trx = new Transaction()
297 | {
298 | //trx headers
299 | expiration = getInfoResult.head_block_time.AddSeconds(60), //expire Seconds
300 | ref_block_num = (UInt16)(getInfoResult.last_irreversible_block_num & 0xFFFF),
301 | ref_block_prefix = getBlockResult.ref_block_prefix,
302 | // trx info
303 | max_net_usage_words = 0,
304 | max_cpu_usage_ms = 0,
305 | delay_sec = 0,
306 | context_free_actions = new List(),
307 | transaction_extensions = new List(),
308 | actions = new List()
309 | {
310 | new Core.Api.v1.Action()
311 | {
312 | account = "eosio.token",
313 | authorization = new List()
314 | {
315 | new PermissionLevel() {actor = "player1", permission = "active" }
316 | },
317 | name = "transfer",
318 | data = new Dictionary() {
319 | { "from", "player1" },
320 | { "to", "player2" },
321 | { "quantity", "1.0000 EOS" },
322 | { "memo", "hello crypto world!" }
323 | }
324 | }
325 | }
326 | };
327 |
328 | var abiSerializer = new AbiSerializationProvider(DefaultApi);
329 | var packedTrx = await abiSerializer.SerializePackedTransaction(trx);
330 | var requiredKeys = new List() { "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" };
331 | var signatures = await EosConfig.SignProvider.Sign(DefaultApi.Config.ChainId, requiredKeys, packedTrx);
332 |
333 | return await DefaultApi.PushTransaction(new PushTransactionRequest()
334 | {
335 | signatures = signatures.ToArray(),
336 | compression = 0,
337 | packed_context_free_data = "",
338 | packed_trx = SerializationHelper.ByteArrayToHexString(packedTrx)
339 | });
340 | }
341 | }
342 | }
343 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.UnitTests.Core/EosSharp.UnitTests.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/EosSharp/EosSharp.UnitTests.Core/EosTestCasesDef.t4:
--------------------------------------------------------------------------------
1 | <#+
2 | string[] ApiUnitTestCases = new string[] {
3 | "GetInfo",
4 | "GetAccount",
5 | "GetCode",
6 | "GetAbi",
7 | "GetRawCodeAndAbi",
8 | "GetRawAbi",
9 | "AbiJsonToBin",
10 | "AbiBinToJson",
11 | "GetRequiredKeys",
12 | "GetBlock",
13 | "GetBlockHeaderState",
14 | "GetTableRows",
15 | "GetTableByScope",
16 | "GetCurrencyBalance",
17 | "GetCurrencyStats",
18 | "GetProducers",
19 | "GetProducerSchedule",
20 | "GetScheduledTransactions",
21 | "PushTransaction",
22 | "GetActions",
23 | "GetTransaction",
24 | "GetKeyAccounts",
25 | "GetControlledAccounts"
26 | };
27 |
28 | string[] EosUnitTestCases = new string[] {
29 | "GetBlock",
30 | "GetTableRows",
31 | "GetTableRowsGeneric",
32 | "GetProducers",
33 | "GetScheduledTransactions",
34 | "CreateTransactionArrayData",
35 | "CreateTransactionActionArrayStructData",
36 | "CreateTransactionAnonymousObjectData",
37 | "CreateTransaction",
38 | "CreateNewAccount"
39 | };
40 |
41 | string[] SerializationUnitTestCases = new string[] {
42 | "DoubleSerialization",
43 | "DecimalSerialization"
44 | };
45 |
46 | #>
--------------------------------------------------------------------------------
/EosSharp/EosSharp.UnitTests.Core/EosUnitTestCases.cs:
--------------------------------------------------------------------------------
1 | using EosSharp.Core;
2 | using EosSharp.Core.Api.v1;
3 | using System;
4 | using System.Collections;
5 | using System.Collections.Generic;
6 | using System.Threading.Tasks;
7 |
8 | namespace EosSharp.UnitTests
9 | {
10 | public class EosUnitTestCases
11 | {
12 | EosBase Eos { get; set; }
13 | public EosUnitTestCases(EosBase eos)
14 | {
15 | Eos = eos;
16 | }
17 |
18 | public Task GetBlock()
19 | {
20 | return Eos.GetBlock("13503532");
21 | }
22 |
23 | public Task GetTableRows()
24 | {
25 | return Eos.GetTableRows(new GetTableRowsRequest()
26 | {
27 | json = false,
28 | code = "eosio.token",
29 | scope = "EOS",
30 | table = "stat"
31 | });
32 | }
33 |
34 | [Serializable]
35 | class Stat
36 | {
37 | public string issuer { get; set; }
38 | public string max_supply { get; set; }
39 | public string supply { get; set; }
40 | }
41 |
42 | public Task GetTableRowsGeneric()
43 | {
44 | return Eos.GetTableRows(new GetTableRowsRequest()
45 | {
46 | json = true,
47 | code = "eosio.token",
48 | scope = "EOS",
49 | table = "stat"
50 | });
51 | }
52 |
53 | public Task GetProducers()
54 | {
55 | return Eos.GetProducers(new GetProducersRequest()
56 | {
57 | json = false
58 | });
59 | }
60 |
61 | public Task GetScheduledTransactions()
62 | {
63 | return Eos.GetScheduledTransactions(new GetScheduledTransactionsRequest()
64 | {
65 | json = false
66 | });
67 | }
68 |
69 | public Task CreateTransactionArrayData()
70 | {
71 | return Eos.CreateTransaction(new Transaction()
72 | {
73 | actions = new List()
74 | {
75 | new Core.Api.v1.Action()
76 | {
77 | account = "platform",
78 | authorization = new List()
79 | {
80 | new PermissionLevel() {actor = "player1", permission = "active" }
81 | },
82 | name = "testarr",
83 | data = new { user = "player1", array = new List() { 1, 6, 3} }
84 | //data = new { user = "player1", array = new UInt64[] { 1, 6, 3} }
85 | //data = new { user = "player1", array = new Queue(new UInt64[] { 1, 6, 3}) }
86 | //data = new { user = "player1", array = new Stack(new UInt64[] { 1, 6, 3}) }
87 | //data = new { user = "player1", array = new ArrayList() { 1, 6, 3} }
88 | }
89 | }
90 | });
91 | }
92 |
93 | public Task CreateTransactionActionArrayStructData()
94 | {
95 | var args = new List