defmodule Stellar.TxBuild.SorobanAuthorizedInvocation do @moduledoc """ `SorobanAuthorizedInvocation` struct definition. """ alias Stellar.TxBuild.SorobanAuthorizedFunction alias StellarBase.XDR.{SorobanAuthorizedInvocation, SorobanAuthorizedInvocationList} @behaviour Stellar.TxBuild.XDR @type error :: {:error, atom()} @type validation :: {:ok, any()} | error() @type soroban_function :: SorobanAuthorizedFunction.t() @type sub_invocations :: list(SorobanAuthorizedInvocation.t()) @type t :: %__MODULE__{function: soroban_function(), sub_invocations: sub_invocations()} defstruct [:function, :sub_invocations] @impl true def new(args, opts \\ []) def new(args, _opts) when is_list(args) do function = Keyword.get(args, :function) sub_invocations = Keyword.get(args, :sub_invocations) with {:ok, function} <- validate_function(function), {:ok, sub_invocations} <- validate_sub_invocations(sub_invocations) do %__MODULE__{function: function, sub_invocations: sub_invocations} end end def new(_args, _opts), do: {:error, :invalid_soroban_auth_invocation} @impl true def to_xdr(%__MODULE__{function: function, sub_invocations: sub_invocations}) do sub_invocations = sub_invocations |> Enum.map(&to_xdr/1) |> SorobanAuthorizedInvocationList.new() function |> SorobanAuthorizedFunction.to_xdr() |> SorobanAuthorizedInvocation.new(sub_invocations) end def to_xdr(_struct), do: {:error, :invalid_struct} @spec validate_function(function :: soroban_function()) :: validation() defp validate_function(%SorobanAuthorizedFunction{} = function), do: {:ok, function} defp validate_function(_function), do: {:error, :invalid_function} @spec validate_sub_invocations(sub_invocations :: sub_invocations()) :: validation() defp validate_sub_invocations(sub_invocations) do if Enum.all?(sub_invocations, &is_soroban_auth_invocation?/1), do: {:ok, sub_invocations}, else: {:error, :invalid_sub_invocations} end @spec is_soroban_auth_invocation?(t()) :: boolean() defp is_soroban_auth_invocation?(%__MODULE__{}), do: true defp is_soroban_auth_invocation?(_struct), do: false end