defmodule DexiWeb.SignTxController do use DexiWeb, :controller require Logger alias Dexi.ChainTransactions alias Dexi.Grids alias Dexi.GridsCallData def show(conn, %{"message_id" => message_id}) do with {:ok, {_requester, pubkey, unsigned_tx}} <- GridsCallData.get(message_id), {:ok, network_id} <- Grids.network_id(), {:ok, dead_drop} <- Grids.create_dead_drop(%{ payload: unsigned_tx, public_id: pubkey, network_id: network_id, type: "tx" }) do json(conn, dead_drop_data(dead_drop)) else _error -> not_found(conn) end end def sign( conn, %{"message_id" => message_id, "public_id" => pubkey, "payload" => signed_tx} = params ) do case GridsCallData.get(message_id) do {:ok, {requester, ^pubkey, unsigned_tx}} -> submit_signed_tx(conn, requester, pubkey, unsigned_tx, signed_tx, message_id, params) {:ok, {_requester, _other_pubkey, _unsigned_tx}} -> Logger.info("Rejected transaction signature with mismatched public key") not_found(conn) {:error, :not_found} -> not_found(conn) end end def sign(conn, _params), do: not_found(conn) defp submit_signed_tx( conn, requester, pubkey, unsigned_tx, signed_tx, message_id, params ) do with {:ok, dead_drop} <- Grids.create_dead_drop(params), :ok <- ChainTransactions.verify_signed_tx(pubkey, unsigned_tx, signed_tx), {:ok, tx_hash} <- ChainTransactions.post_tx(signed_tx), :ok <- GridsCallData.remove(message_id) do send(requester, {:tx_success, tx_hash}) json(conn, dead_drop_data(dead_drop)) else error -> Logger.info("Transaction signing failed: #{inspect(error)}") send(requester, :tx_failed) not_found(conn) end end defp not_found(conn) do conn |> put_status(:not_found) |> json(%{error: "not_found"}) end defp dead_drop_data(dead_drop) do %{ grids: dead_drop.grids, chain: dead_drop.chain, network_id: dead_drop.network_id, type: dead_drop.type, public_id: dead_drop.public_id, payload: dead_drop.payload, signature: dead_drop.signature } end end