defmodule Forge.Wallet do @moduledoc """ Wallet client """ alias Forge.{AccountState, Crypto, Rpc, Server, Tx.TransferTransaction} @type t :: %{ private_key: String.t(), public_key: String.t(), address: String.t() } @doc """ Create a new eth-like wallet """ @spec new() :: t() def new do private_key = Crypto.create_private_key() public_key = Crypto.create_public_key(private_key) address = Crypto.create_wallet_address(public_key) %{ private_key: Base.encode16(private_key), public_key: Base.encode16(public_key), address: address } end @spec transfer(t(), String.t(), non_neg_integer()) :: :ok | {:error, any} def transfer(%{address: from, public_key: public_key, private_key: private_key}, to, total) do nonce = nonce(from) from |> TransferTransaction.create(to, nonce, total, public_key, private_key) |> Rpc.send() end @spec balance(String.t()) :: non_neg_integer() def balance(address) do apply(Server, :account_balance, [address]) end @spec nonce(String.t()) :: non_neg_integer() def nonce(address) do apply(Server, :account_nonce, [address]) end @spec info(String.t()) :: AccountState.t() def info(address) do apply(Server, :account_info, [address]) end @spec chain_info :: map() def chain_info do apply(Server, :chain_info, []) end end