From a939fb5cde76da185d75ddee2612e1979fdc05ba Mon Sep 17 00:00:00 2001 From: "Abdel @ StarkWare" Date: Mon, 23 Sep 2024 12:45:38 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20mint=20pubkey=20in=20/info?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/gakimint/core/mint.ex | 56 ++++++++++++++++--- .../web/controllers/mint_controller.ex | 7 ++- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/lib/gakimint/core/mint.ex b/lib/gakimint/core/mint.ex index 820f295..64a4158 100644 --- a/lib/gakimint/core/mint.ex +++ b/lib/gakimint/core/mint.ex @@ -4,12 +4,14 @@ defmodule Gakimint.Mint do """ use GenServer - alias Gakimint.Repo + alias Gakimint.{Crypto, Repo} alias Gakimint.Schema.{Key, Keyset, MintConfiguration} import Ecto.Query @keyset_generation_seed_key "keyset_generation_seed" @keyset_generation_derivation_path "m/0'/0'/0'" + @mint_pubkey_key "mint_pubkey" + @mint_privkey_key "mint_privkey" def start_link(_) do GenServer.start_link(__MODULE__, %{}, name: __MODULE__) @@ -17,14 +19,15 @@ defmodule Gakimint.Mint do @impl true def init(_) do - {:ok, %{keysets: []}, {:continue, :load_keysets}} + {:ok, %{keysets: [], mint_pubkey: nil}, {:continue, :load_keysets_and_mint_key}} end @impl true - def handle_continue(:load_keysets, state) do + def handle_continue(:load_keysets_and_mint_key, state) do seed = get_or_create_seed() keysets = load_or_create_keysets(seed) - {:noreply, %{state | keysets: keysets}} + {_, mint_pubkey} = get_or_create_mint_key(seed) + {:noreply, %{state | keysets: keysets, mint_pubkey: mint_pubkey}} end defp get_or_create_seed do @@ -56,11 +59,51 @@ defmodule Gakimint.Mint do end end + defp get_or_create_mint_key(seed) do + case {Repo.get_by(MintConfiguration, key: @mint_pubkey_key), + Repo.get_by(MintConfiguration, key: @mint_privkey_key)} do + {nil, nil} -> + {privkey, pubkey} = derive_mint_key(seed) + + %MintConfiguration{} + |> MintConfiguration.changeset(%{ + key: @mint_pubkey_key, + value: Base.encode16(pubkey, case: :lower) + }) + |> Repo.insert!() + + %MintConfiguration{} + |> MintConfiguration.changeset(%{ + key: @mint_privkey_key, + value: Base.encode16(privkey, case: :lower) + }) + |> Repo.insert!() + + {privkey, pubkey} + + {pubkey_config, privkey_config} -> + pubkey = Base.decode16!(pubkey_config.value, case: :lower) + privkey = Base.decode16!(privkey_config.value, case: :lower) + {privkey, pubkey} + end + end + + defp derive_mint_key(seed) do + private_key = :crypto.hash(:sha256, seed) + {private_key, public_key} = Crypto.generate_keypair(private_key) + {private_key, public_key} + end + @impl true def handle_call(:get_keysets, _from, state) do {:reply, state.keysets, state} end + @impl true + def handle_call(:get_mint_pubkey, _from, state) do + {:reply, state.mint_pubkey, state} + end + # Public API def get_keysets do @@ -77,10 +120,7 @@ defmodule Gakimint.Mint do end def get_pubkey do - [keyset | _] = get_keysets() - keys = get_keys_for_keyset(keyset.id) - keys_map = Enum.into(keys, %{}, fn key -> {key.amount, key.public_key} end) - keys_map["1"] + GenServer.call(__MODULE__, :get_mint_pubkey) end def get_active_keysets do diff --git a/lib/gakimint/web/controllers/mint_controller.ex b/lib/gakimint/web/controllers/mint_controller.ex index dc06f64..202610b 100644 --- a/lib/gakimint/web/controllers/mint_controller.ex +++ b/lib/gakimint/web/controllers/mint_controller.ex @@ -1,11 +1,12 @@ defmodule Gakimint.Web.MintController do use Gakimint.Web, :controller + alias Gakimint.Mint alias Gakimint.Web.{Keys, KeysetResponse} def info(conn, _params) do info = %{ name: "Gakimint Cashu Mint", - pubkey: "", + pubkey: Base.encode16(Mint.get_pubkey(), case: :lower), version: "Gakimint/0.1.0", description: "An Elixir implementation of Cashu Mint", description_long: "A Cashu Mint implementation in Elixir.", @@ -66,11 +67,11 @@ defmodule Gakimint.Web.MintController do end def keys(conn, _params) do - keysets = Gakimint.Mint.get_active_keysets() + keysets = Mint.get_active_keysets() keysets_responses = Enum.map(keysets, fn keyset -> - keys = Gakimint.Mint.get_keys_for_keyset(keyset.id) + keys = Mint.get_keys_for_keyset(keyset.id) keys_list = Enum.map(keys, fn key -> {key.amount, Base.encode16(key.public_key, case: :lower)} end)