Skip to content

Commit

Permalink
Merge pull request #73 from alisinabh/add-get-balance
Browse files Browse the repository at this point in the history
Implement `Ethers.get_balance/2` with tests
  • Loading branch information
alisinabh authored Jan 4, 2024
2 parents eb676f4 + d4f019f commit cb6ecc8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### New features

- Add `Ethers.get_balance/2` function to query native chain balance of accounts.

### Bug fixes

- Encode integers to hex even when they are part of params
Expand Down
44 changes: 43 additions & 1 deletion lib/ethers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ defmodule Ethers do
alias Ethers.Utils

@option_keys [:rpc_client, :rpc_opts, :signer, :signer_opts, :tx_type]
@hex_decode_post_process [:estimate_gas, :current_gas_price, :current_block_number]
@hex_decode_post_process [
:estimate_gas,
:current_gas_price,
:current_block_number,
:get_balance
]
@rpc_actions_map %{
call: :eth_call,
chain_id: :eth_chain_id,
Expand Down Expand Up @@ -108,6 +113,29 @@ defmodule Ethers do
|> post_process(nil, :current_block_number)
end

@doc """
Returns the native token (ETH) balance of an account in wei.
## Parameters
- account: Account which the balance is queried for.
- overrides:
- block: The block you want to query the balance of account in (defaults to `latest`).
- rpc_client: The RPC module to use for this request (overrides default).
- rpc_opts: Specific RPC options to specify for this request.
"""
@spec get_balance(Types.t_address(), Keyword.t()) ::
{:ok, non_neg_integer()} | {:error, term()}
def get_balance(account, overrides \\ []) do
{opts, overrides} = Keyword.split(overrides, @option_keys)

{rpc_client, rpc_opts} = get_rpc_client(opts)

with {:ok, account, block} <- pre_process(account, overrides, :get_balance, opts) do
rpc_client.eth_get_balance(account, block, rpc_opts)
|> post_process(nil, :get_balance)
end
end

@doc """
Deploys a contract to the blockchain.
Expand Down Expand Up @@ -485,6 +513,20 @@ defmodule Ethers do
end
end

defp pre_process(account, overrides, :get_balance = _action, _opts) do
block =
case Keyword.get(overrides, :block, "latest") do
number when is_integer(number) -> Utils.integer_to_hex(number)
v -> v
end

case account do
"0x" <> _ -> {:ok, account, block}
<<_::binary-20>> -> {:ok, Utils.hex_encode(account), block}
_ -> {:error, :invalid_account}
end
end

defp pre_process(contract_binary, overrides, :deploy = _action, opts) do
{encoded_constructor, overrides} = Keyword.pop(overrides, :encoded_constructor)

Expand Down
19 changes: 19 additions & 0 deletions test/ethers_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,25 @@ defmodule EthersTest do
end
end

describe "get_balance" do
test "returns correct balance for account" do
assert {:ok, 0} == Ethers.get_balance("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")

assert {:ok, 1_000_000_000_000_000_000_000} ==
Ethers.get_balance("0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC")
end

test "works with binary accounts" do
bin = Ethers.Utils.hex_decode!("0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC")

assert {:ok, 1_000_000_000_000_000_000_000} == Ethers.get_balance(bin)
end

test "returns error with invalid account" do
assert {:error, :invalid_account} == Ethers.get_balance("invalid account")
end
end

describe "contract deployment" do
test "can deploy a contract given a module which has the binary" do
assert {:ok, tx} = Ethers.deploy(HelloWorldContract, from: @from)
Expand Down

0 comments on commit cb6ecc8

Please sign in to comment.