Merge pull request #396 from poanetwork/sa-api-account-balance
Add account balance API endpointpull/409/head
commit
5c501232c8
@ -0,0 +1,42 @@ |
|||||||
|
defmodule ExplorerWeb.API.RPC.AddressController do |
||||||
|
use ExplorerWeb, :controller |
||||||
|
|
||||||
|
alias Explorer.Chain |
||||||
|
alias Explorer.Chain.{Address, Wei} |
||||||
|
|
||||||
|
def balance(conn, params) do |
||||||
|
with {:address_param, {:ok, address_hash_string}} <- fetch_address(params), |
||||||
|
{:format, {:ok, address_hash}} <- to_address_hash(address_hash_string), |
||||||
|
{:ok, address} <- hash_to_address(address_hash) do |
||||||
|
render(conn, :balance, %{address: address}) |
||||||
|
else |
||||||
|
{:address_param, :error} -> |
||||||
|
conn |
||||||
|
|> put_status(400) |
||||||
|
|> render(:error, error: "Query parameter 'address' is required") |
||||||
|
|
||||||
|
{:format, :error} -> |
||||||
|
conn |
||||||
|
|> put_status(400) |
||||||
|
|> render(:error, error: "Invalid address hash") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
defp fetch_address(params) do |
||||||
|
{:address_param, Map.fetch(params, "address")} |
||||||
|
end |
||||||
|
|
||||||
|
defp to_address_hash(address_hash_string) do |
||||||
|
{:format, Chain.string_to_address_hash(address_hash_string)} |
||||||
|
end |
||||||
|
|
||||||
|
defp hash_to_address(address_hash) do |
||||||
|
address = |
||||||
|
case Chain.hash_to_address(address_hash) do |
||||||
|
{:ok, address} -> address |
||||||
|
{:error, :not_found} -> %Address{fetched_balance: %Wei{value: 0}} |
||||||
|
end |
||||||
|
|
||||||
|
{:ok, address} |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,15 @@ |
|||||||
|
defmodule ExplorerWeb.API.RPC.AddressView do |
||||||
|
use ExplorerWeb, :view |
||||||
|
|
||||||
|
alias ExplorerWeb.API.RPC.RPCView |
||||||
|
|
||||||
|
def render("balance.json", %{address: address}) do |
||||||
|
ether_balance = format_wei_value(address.fetched_balance, :ether, include_unit_label: false) |
||||||
|
data = ether_balance |
||||||
|
RPCView.render("show.json", data: data) |
||||||
|
end |
||||||
|
|
||||||
|
def render("error.json", %{error: error}) do |
||||||
|
RPCView.render("error.json", error: error) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,83 @@ |
|||||||
|
defmodule ExplorerWeb.API.RPC.AddressControllerTest do |
||||||
|
use ExplorerWeb.ConnCase |
||||||
|
|
||||||
|
alias Explorer.Chain.Wei |
||||||
|
|
||||||
|
describe "balance" do |
||||||
|
test "with missing address hash", %{conn: conn} do |
||||||
|
params = %{ |
||||||
|
"module" => "account", |
||||||
|
"action" => "balance" |
||||||
|
} |
||||||
|
|
||||||
|
assert response = |
||||||
|
conn |
||||||
|
|> get("/api", params) |
||||||
|
|> json_response(400) |
||||||
|
|
||||||
|
assert response["message"] =~ "'address' is required" |
||||||
|
assert response["status"] == "0" |
||||||
|
assert Map.has_key?(response, "result") |
||||||
|
refute response["result"] |
||||||
|
end |
||||||
|
|
||||||
|
test "with an invalid address hash", %{conn: conn} do |
||||||
|
params = %{ |
||||||
|
"module" => "account", |
||||||
|
"action" => "balance", |
||||||
|
"address" => "badhash" |
||||||
|
} |
||||||
|
|
||||||
|
assert response = |
||||||
|
conn |
||||||
|
|> get("/api", params) |
||||||
|
|> json_response(400) |
||||||
|
|
||||||
|
assert response["message"] =~ "Invalid address hash" |
||||||
|
assert response["status"] == "0" |
||||||
|
assert Map.has_key?(response, "result") |
||||||
|
refute response["result"] |
||||||
|
end |
||||||
|
|
||||||
|
test "with an address that doesn't exist", %{conn: conn} do |
||||||
|
params = %{ |
||||||
|
"module" => "account", |
||||||
|
"action" => "balance", |
||||||
|
"address" => "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" |
||||||
|
} |
||||||
|
|
||||||
|
assert response = |
||||||
|
conn |
||||||
|
|> get("/api", params) |
||||||
|
|> json_response(200) |
||||||
|
|
||||||
|
assert response["result"] == "0" |
||||||
|
assert response["status"] == "1" |
||||||
|
assert response["message"] == "OK" |
||||||
|
end |
||||||
|
|
||||||
|
test "with a valid address", %{conn: conn} do |
||||||
|
address = insert(:address, fetched_balance: 100) |
||||||
|
|
||||||
|
params = %{ |
||||||
|
"module" => "account", |
||||||
|
"action" => "balance", |
||||||
|
"address" => "#{address.hash}" |
||||||
|
} |
||||||
|
|
||||||
|
expected_balance = |
||||||
|
address.fetched_balance |
||||||
|
|> Wei.to(:ether) |
||||||
|
|> Decimal.to_string(:normal) |
||||||
|
|
||||||
|
assert response = |
||||||
|
conn |
||||||
|
|> get("/api", params) |
||||||
|
|> json_response(200) |
||||||
|
|
||||||
|
assert response["result"] == expected_balance |
||||||
|
assert response["status"] == "1" |
||||||
|
assert response["message"] == "OK" |
||||||
|
end |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue