diff --git a/lib/archethic/contracts/contract/state.ex b/lib/archethic/contracts/contract/state.ex index ebdb9871e..3a6fb9b4f 100644 --- a/lib/archethic/contracts/contract/state.ex +++ b/lib/archethic/contracts/contract/state.ex @@ -29,4 +29,39 @@ defmodule Archethic.Contracts.Contract.State do """ @spec deserialize(bitstring()) :: {t(), bitstring()} def deserialize(bitsting), do: TypedEncoding.deserialize(bitsting, :compact) + + @doc """ + Return a valid JSON of the given state + Handles the fact that keys can be non-string + """ + @spec to_json(state :: t()) :: map() + def to_json(state) do + serialize_map_keys(state) + end + + @doc """ + Returns the state as a prettified JSON + Handles the fact that keys can be non-string + """ + @spec format(state :: t()) :: String.t() + def format(state) do + Jason.encode!(to_json(state), pretty: true) + end + + defp serialize_map_keys(map) when is_map(map) do + map + |> Enum.reduce(%{}, fn + {k, v}, acc when is_binary(k) -> + Map.put(acc, k, serialize_map_keys(v)) + + {k, v}, acc -> + Map.put(acc, Jason.encode!(k), serialize_map_keys(v)) + end) + end + + defp serialize_map_keys(list) when is_list(list) do + Enum.map(list, &serialize_map_keys/1) + end + + defp serialize_map_keys(term), do: term end diff --git a/lib/archethic_web/api/graphql/schema/transaction_type.ex b/lib/archethic_web/api/graphql/schema/transaction_type.ex index aeac57e09..3082b0912 100644 --- a/lib/archethic_web/api/graphql/schema/transaction_type.ex +++ b/lib/archethic_web/api/graphql/schema/transaction_type.ex @@ -4,6 +4,7 @@ defmodule ArchethicWeb.API.GraphQL.Schema.TransactionType do use Absinthe.Schema.Notation alias ArchethicWeb.API.GraphQL.Schema.Resolver + alias Archethic.Contracts.Contract.State alias Archethic.TransactionChain.Transaction @@ -209,7 +210,7 @@ defmodule ArchethicWeb.API.GraphQL.Schema.TransactionType do [State] represents the smart contract state """ scalar :state do - serialize(& &1) + serialize(&State.to_json/1) end @desc """ diff --git a/lib/archethic_web/explorer/live/transaction_details_live.ex b/lib/archethic_web/explorer/live/transaction_details_live.ex index d23daead1..846a70262 100644 --- a/lib/archethic_web/explorer/live/transaction_details_live.ex +++ b/lib/archethic_web/explorer/live/transaction_details_live.ex @@ -332,7 +332,7 @@ defmodule ArchethicWeb.Explorer.TransactionDetailsLive do end def print_state(%UnspentOutput{encoded_payload: encoded_state}) do - encoded_state |> State.deserialize() |> elem(0) |> inspect(pretty: true) + encoded_state |> State.deserialize() |> elem(0) |> State.format() end defp similar?( diff --git a/test/archethic/contracts/state_test.exs b/test/archethic/contracts/state_test.exs index ac0cf816c..aaa887d36 100644 --- a/test/archethic/contracts/state_test.exs +++ b/test/archethic/contracts/state_test.exs @@ -14,6 +14,14 @@ defmodule Archethic.Contracts.Contract.StateTest do end end + describe "format/1" do + test "should return a valid JSON prettified" do + state = complex_state() + + assert {:ok, _} = State.format(state) |> Jason.decode() + end + end + defp complex_state() do %{ "foo" => "bar",