diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a454a6a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# 0.1.2 +* Added generic request method + +# 0.1.1 +* Added necessary JSON header for parity diff --git a/README.md b/README.md index 2e42ebc..bfcc705 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Add Ethereumex to your `mix.exs` dependencies: 1. Add `ethereumex` to your list of dependencies in `mix.exs`: ```elixir def deps do - [{:ethereumex, "~> 0.1.0"}] + [{:ethereumex, "~> 0.1.2"}] end ``` @@ -33,9 +33,6 @@ config :ethereumex, ## Usage -### Note -Currently only official [DApp APIs](https://github.com/ethereum/wiki/wiki/JSON-RPC) are implemented. More features (new api methods, smart contract creation) will be added soon. - ### Available methods: * web3_clientVersion @@ -119,6 +116,19 @@ iex> Ethereumex.HttpClient.eth_get_balance(["0x407d73d8a49eeb85d32cf465507dd71d5 ``` Note that all method names are snakecases, so, for example, shh_getMessages method has corresponding Ethereumex.HttpClient.shh_get_messages/1 method +### Custom requests +Many Ethereum protocol implementations support additional JSON-RPC API methods. To use them, you should call Ethereumex.HttpClient.send_request/2 method. + +For example, let's call geth's rpc_modules method. + +```elixir +iex> Ethereumex.HttpClient.send_request("rpc_modules") +{:ok, + %{"id" => 5, "jsonrpc" => "2.0", + "result" => %{"eth" => "1.0", "net" => "1.0", "rpc" => "1.0", + "web3" => "1.0"}}} +``` + ## Contributing 1. [Fork it!](http://github.com/ayrat555/ethereumex/fork) diff --git a/fixture/vcr_cassettes/http_client_custom_request.json b/fixture/vcr_cassettes/http_client_custom_request.json new file mode 100644 index 0000000..1b6b33a --- /dev/null +++ b/fixture/vcr_cassettes/http_client_custom_request.json @@ -0,0 +1,22 @@ +[ + { + "request": { + "body": "{\"params\":[],\"method\":\"rpc_modules\",\"jsonrpc\":\"2.0\",\"id\":3}", + "headers": [], + "method": "post", + "options": [], + "request_body": "", + "url": "http://localhost:8545" + }, + "response": { + "body": "{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"eth\":\"1.0\",\"net\":\"1.0\",\"rpc\":\"1.0\",\"web3\":\"1.0\"}}\n", + "headers": { + "Content-Type": "application/json", + "Date": "Sun, 24 Sep 2017 15:55:06 GMT", + "Content-Length": "85" + }, + "status_code": 200, + "type": "ok" + } + } +] \ No newline at end of file diff --git a/lib/ethereumex/client.ex b/lib/ethereumex/client.ex index 13f389d..d4a95f1 100644 --- a/lib/ethereumex/client.ex +++ b/lib/ethereumex/client.ex @@ -1,5 +1,5 @@ defmodule Ethereumex.Client do - @callback request(payload :: map) :: tuple + @callback request(map()) :: any() @moduledoc false alias Ethereumex.Client.Utils @@ -34,16 +34,22 @@ defmodule Ethereumex.Client do methods |> Enum.each(fn({original_name, formatted_name}) -> def unquote(formatted_name)(params \\ []) when is_list(params) do - params = params |> add_method_info(unquote(original_name)) - - GenServer.call __MODULE__, {:request, params} + send_request(unquote(original_name), params) end end) - def request(_) do + @spec send_request(binary(), [binary()] | [map()]) :: any() + def send_request(method_name, params \\ []) when is_list(params) do + params = params |> add_method_info(method_name) + + GenServer.call __MODULE__, {:request, params} + end + + @spec request(map()) :: any() + def request(_payload) do end - @spec add_method_info([binary] | [map], binary()) :: map() + @spec add_method_info([binary()] | [map()], binary()) :: map() defp add_method_info(params, method_name) do %{} |> Map.put("method", method_name) diff --git a/lib/ethereumex/http_client.ex b/lib/ethereumex/http_client.ex index de1353e..9e859ef 100644 --- a/lib/ethereumex/http_client.ex +++ b/lib/ethereumex/http_client.ex @@ -3,13 +3,14 @@ defmodule Ethereumex.HttpClient do import Ethereumex.Config @moduledoc false - @spec post_request(map()) :: {:ok | :error, any()} + @spec request(map()) :: {:ok | :error, any()} def request(payload) do payload |> encode_payload |> post_request end + @spec encode_payload(map()) :: binary() defp encode_payload(payload) do payload |> Poison.encode! end diff --git a/mix.exs b/mix.exs index 248c7de..5789481 100644 --- a/mix.exs +++ b/mix.exs @@ -3,7 +3,7 @@ defmodule Ethereumex.Mixfile do def project do [app: :ethereumex, - version: "0.1.0", + version: "0.1.2", elixir: "~> 1.4", description: "Elixir JSON-RPC client for the Ethereum blockchain", package: [ diff --git a/test/ethereum/http_client_test.exs b/test/ethereum/http_client_test.exs index 6322aa5..6ba96b6 100644 --- a/test/ethereum/http_client_test.exs +++ b/test/ethereum/http_client_test.exs @@ -58,4 +58,23 @@ defmodule Ethereumex.HttpClientTest do } = result end end + + test "sends custom geth request" do + use_cassette "http_client_custom_request" do + result = HttpClient.send_request("rpc_modules") + + {:ok, + %{"id" => 3, + "jsonrpc" => "2.0", + "result" => + %{ + "eth" => "1.0", + "net" => "1.0", + "rpc" => "1.0", + "web3" => "1.0" + } + } + } = result + end + end end