Skip to content

Commit cb6ecc8

Browse files
authored
Merge pull request #73 from alisinabh/add-get-balance
Implement `Ethers.get_balance/2` with tests
2 parents eb676f4 + d4f019f commit cb6ecc8

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### New features
6+
7+
- Add `Ethers.get_balance/2` function to query native chain balance of accounts.
8+
59
### Bug fixes
610

711
- Encode integers to hex even when they are part of params

lib/ethers.ex

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ defmodule Ethers do
6969
alias Ethers.Utils
7070

7171
@option_keys [:rpc_client, :rpc_opts, :signer, :signer_opts, :tx_type]
72-
@hex_decode_post_process [:estimate_gas, :current_gas_price, :current_block_number]
72+
@hex_decode_post_process [
73+
:estimate_gas,
74+
:current_gas_price,
75+
:current_block_number,
76+
:get_balance
77+
]
7378
@rpc_actions_map %{
7479
call: :eth_call,
7580
chain_id: :eth_chain_id,
@@ -108,6 +113,29 @@ defmodule Ethers do
108113
|> post_process(nil, :current_block_number)
109114
end
110115

116+
@doc """
117+
Returns the native token (ETH) balance of an account in wei.
118+
119+
## Parameters
120+
- account: Account which the balance is queried for.
121+
- overrides:
122+
- block: The block you want to query the balance of account in (defaults to `latest`).
123+
- rpc_client: The RPC module to use for this request (overrides default).
124+
- rpc_opts: Specific RPC options to specify for this request.
125+
"""
126+
@spec get_balance(Types.t_address(), Keyword.t()) ::
127+
{:ok, non_neg_integer()} | {:error, term()}
128+
def get_balance(account, overrides \\ []) do
129+
{opts, overrides} = Keyword.split(overrides, @option_keys)
130+
131+
{rpc_client, rpc_opts} = get_rpc_client(opts)
132+
133+
with {:ok, account, block} <- pre_process(account, overrides, :get_balance, opts) do
134+
rpc_client.eth_get_balance(account, block, rpc_opts)
135+
|> post_process(nil, :get_balance)
136+
end
137+
end
138+
111139
@doc """
112140
Deploys a contract to the blockchain.
113141
@@ -485,6 +513,20 @@ defmodule Ethers do
485513
end
486514
end
487515

516+
defp pre_process(account, overrides, :get_balance = _action, _opts) do
517+
block =
518+
case Keyword.get(overrides, :block, "latest") do
519+
number when is_integer(number) -> Utils.integer_to_hex(number)
520+
v -> v
521+
end
522+
523+
case account do
524+
"0x" <> _ -> {:ok, account, block}
525+
<<_::binary-20>> -> {:ok, Utils.hex_encode(account), block}
526+
_ -> {:error, :invalid_account}
527+
end
528+
end
529+
488530
defp pre_process(contract_binary, overrides, :deploy = _action, opts) do
489531
{encoded_constructor, overrides} = Keyword.pop(overrides, :encoded_constructor)
490532

test/ethers_test.exs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ defmodule EthersTest do
4141
end
4242
end
4343

44+
describe "get_balance" do
45+
test "returns correct balance for account" do
46+
assert {:ok, 0} == Ethers.get_balance("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
47+
48+
assert {:ok, 1_000_000_000_000_000_000_000} ==
49+
Ethers.get_balance("0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC")
50+
end
51+
52+
test "works with binary accounts" do
53+
bin = Ethers.Utils.hex_decode!("0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC")
54+
55+
assert {:ok, 1_000_000_000_000_000_000_000} == Ethers.get_balance(bin)
56+
end
57+
58+
test "returns error with invalid account" do
59+
assert {:error, :invalid_account} == Ethers.get_balance("invalid account")
60+
end
61+
end
62+
4463
describe "contract deployment" do
4564
test "can deploy a contract given a module which has the binary" do
4665
assert {:ok, tx} = Ethers.deploy(HelloWorldContract, from: @from)

0 commit comments

Comments
 (0)