diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e4984e..95920ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 0.3.3 +* Added dynamic url input(https://github.com/exthereum/ethereumex/pull/37) + # 0.3.2 * Fix eth_getLogs mathod params (https://github.com/exthereum/ethereumex/pull/20) diff --git a/README.md b/README.md index 466a4ee..1f85284 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.3.2"}] + [{:ethereumex, "~> 0.3.3"}] end ``` @@ -102,6 +102,10 @@ config :ethereumex, iex> Ethereumex.HttpClient.web3_client_version {:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"} +# Using the url option will overwrite the configuration +iex> Ethereumex.HttpClient.web3_client_version(url: "http://localhost:8545") +{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"} + iex> Ethereumex.HttpClient.web3_sha3("wrong_param") {:error, %{"code" => -32602, "message" => "Invalid params: invalid format."}} diff --git a/lib/ethereumex/client/behaviour.ex b/lib/ethereumex/client/behaviour.ex index ec6e950..d86e4c1 100644 --- a/lib/ethereumex/client/behaviour.ex +++ b/lib/ethereumex/client/behaviour.ex @@ -76,6 +76,6 @@ defmodule Ethereumex.Client.Behaviour do # actual request methods @callback request(binary(), list(binary()), keyword()) :: {:ok, any() | [any()]} | error - @callback single_request(map()) :: {:ok, any() | [any()]} | error + @callback single_request(map(), keyword()) :: {:ok, any() | [any()]} | error @callback batch_request([{atom(), list(binary())}]) :: {:ok, [any()]} | error end diff --git a/lib/ethereumex/client/macro.ex b/lib/ethereumex/client/macro.ex index 77496d0..431a7d1 100644 --- a/lib/ethereumex/client/macro.ex +++ b/lib/ethereumex/client/macro.ex @@ -419,14 +419,17 @@ defmodule Ethereumex.Client.Macro do @spec request(binary(), list(binary() | boolean | map), keyword()) :: {:ok, any() | [any()]} | error + def request(_name, _params, batch: true, url: _url), + do: raise("Cannot use batch and url options at the same time") + def request(name, params, batch: true) do name |> add_request_info(params) end - def request(name, params, _) do + def request(name, params, opts) do name |> add_request_info(params) - |> server_request + |> server_request(opts) end @spec batch_request([{atom(), list(binary())}]) :: {:ok, [any()]} | error @@ -441,8 +444,8 @@ defmodule Ethereumex.Client.Macro do |> server_request end - defp server_request(params) do - GenServer.call(__MODULE__, {:request, params}) + defp server_request(params, opts \\ []) do + GenServer.call(__MODULE__, {:request, params, opts}) end def start_link do @@ -453,11 +456,11 @@ defmodule Ethereumex.Client.Macro do GenServer.cast(__MODULE__, :reset_id) end - def single_request(params) do + def single_request(params, opts) do {:error, :not_implemented} end - defoverridable single_request: 1 + defoverridable single_request: 2 end end end diff --git a/lib/ethereumex/client/server.ex b/lib/ethereumex/client/server.ex index 024bc77..e5206d7 100644 --- a/lib/ethereumex/client/server.ex +++ b/lib/ethereumex/client/server.ex @@ -3,11 +3,15 @@ defmodule Ethereumex.Client.Server do @moduledoc false + def init(args) do + {:ok, args} + end + def start_link(module) when is_atom(module) do GenServer.start_link(__MODULE__, {module, 0}, name: module) end - def handle_call({:request, params}, _from, {module, id}) when is_list(params) do + def handle_call({:request, params, opts}, _from, {module, id}) when is_list(params) do params = params |> Enum.with_index() @@ -15,15 +19,15 @@ defmodule Ethereumex.Client.Server do Map.put(req_data, "id", index + id) end) - response = apply(module, :single_request, [params]) + response = apply(module, :single_request, [params, opts]) {:reply, response, {module, id + Enum.count(params)}} end - def handle_call({:request, params}, _from, {module, id}) do + def handle_call({:request, params, opts}, _from, {module, id}) do params = Map.put(params, "id", id) - response = apply(module, :single_request, [params]) + response = apply(module, :single_request, [params, opts]) {:reply, response, {module, id + 1}} end diff --git a/lib/ethereumex/http_client.ex b/lib/ethereumex/http_client.ex index 37c23af..b8fd423 100644 --- a/lib/ethereumex/http_client.ex +++ b/lib/ethereumex/http_client.ex @@ -3,11 +3,11 @@ defmodule Ethereumex.HttpClient do import Ethereumex.Config @moduledoc false - @spec single_request(map()) :: {:ok, any() | [any()]} | error - def single_request(payload) do + @spec single_request(map(), []) :: {:ok, any() | [any()]} | error + def single_request(payload, opts \\ []) do payload |> encode_payload - |> post_request + |> post_request(opts) end @spec encode_payload(map()) :: binary() @@ -15,12 +15,13 @@ defmodule Ethereumex.HttpClient do payload |> Poison.encode!() end - @spec post_request(binary()) :: {:ok | :error, any()} - defp post_request(payload) do + @spec post_request(binary(), []) :: {:ok | :error, any()} + defp post_request(payload, opts) do headers = [{"Content-Type", "application/json"}] options = Ethereumex.Config.http_options() + url = Keyword.get(opts, :url) || rpc_url() - with {:ok, response} <- HTTPoison.post(rpc_url(), payload, headers, options), + with {:ok, response} <- HTTPoison.post(url, payload, headers, options), %HTTPoison.Response{body: body, status_code: code} = response do decode_body(body, code) else diff --git a/mix.exs b/mix.exs index a4fafc4..a594fcd 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Ethereumex.Mixfile do def project do [ app: :ethereumex, - version: "0.3.2", + version: "0.3.3", elixir: "~> 1.6", description: "Elixir JSON-RPC client for the Ethereum blockchain", package: [ diff --git a/test/ethereumex/client/macro_test.exs b/test/ethereumex/client/macro_test.exs index ba9b9b8..6b9ecf2 100644 --- a/test/ethereumex/client/macro_test.exs +++ b/test/ethereumex/client/macro_test.exs @@ -4,10 +4,10 @@ defmodule Ethereumex.Client.MacroTest do defmodule ClientMock do use Ethereumex.Client.Macro - def single_request(payload) do + def single_request(payload, opts) do %{"method" => method, "jsonrpc" => "2.0", "params" => params} = payload - {method, params} + {method, params, opts} end end @@ -19,7 +19,11 @@ defmodule Ethereumex.Client.MacroTest do end def assert_method({ex_method, eth_method}, params, payload) do - {^eth_method, ^payload} = apply(ClientMock, String.to_atom(ex_method), params) + {^eth_method, ^payload, _opts} = apply(ClientMock, String.to_atom(ex_method), params) + end + + def assert_opts({ex_method, _eth_method}, params, opts) do + {_eth_method, _payload, ^opts} = apply(ClientMock, String.to_atom(ex_method), params) end def make_tuple(ex_method) do @@ -69,7 +73,18 @@ defmodule Ethereumex.Client.MacroTest do topics: ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] } - test ".web3_client_version/0", do: Helpers.check("web3_client_version") + describe ".web3_client_version/0" do + test "with configuration url", do: Helpers.check("web3_client_version") + + test "with dynamic url", + do: + Helpers.assert_opts( + {"web3_client_version", "web3_client_version"}, + [[url: "http://localhost:4000"]], + url: "http://localhost:4000" + ) + end + test ".net_version/0", do: Helpers.check("net_version") test ".net_peer_count/0", do: Helpers.check("net_peer_count") test ".net_listening/0", do: Helpers.check("net_listening")