lib/bbox/voters.ex

defmodule Bbox.Voters do
  alias Bbox.Repo
  alias Bbox.Voters.Voter

  @doc """
  Insert a new voter into the database.
  """
  @spec insert(map()) :: {:ok, %Voter{}} | {:error, charlist()}
  def insert(params \\ %{}) do
    {:ok, voter} =
      %Voter{}
      |> Voter.changeset(params)
      |> Repo.insert()

    :telemetry.execute([:bbox, :voters, :insert], %{voter: voter})

    {:ok, voter}
  end

  @doc """
  Get voter by RSA Private Key.
  """
  @spec get_by_private_key!(binary()) :: %Voter{}
  def get_by_private_key!(private_key) do
    address =
      private_key
      |> Base.decode32!()
      |> X509.PrivateKey.from_pem!()
      |> X509.PublicKey.derive()
      |> X509.PublicKey.to_pem()
      |> Base.encode32()
      |> String.slice(0..20)

    voter = Repo.get_by!(Voter, address: address)

    :telemetry.execute([:bbox, :voters, :get_by_private_key!], %{voter: voter})

    voter
  end
end