defmodule Stellar.TxBuild.SorobanAuthorizedFunction do @moduledoc """ `SorobanAuthorizedFunction` struct definition. """ alias StellarBase.XDR.{SorobanAuthorizedFunction, SorobanAuthorizedFunctionType} alias Stellar.TxBuild.{CreateContractArgs, SorobanAuthorizedContractFunction} @behaviour Stellar.TxBuild.XDR @type error :: {:error, atom()} @type validation :: {:ok, any()} | error() @type type :: :contract_fn | :create_contract_host_fn @type value :: CreateContractArgs.t() | SorobanAuthorizedContractFunction.t() @type t :: %__MODULE__{type: type(), value: value()} defstruct [:type, :value] @allowed_types ~w(contract_fn create_contract_host_fn)a @impl true def new(value, opts \\ []) def new([{type, value}], _opts) when type in @allowed_types do with {:ok, value} <- validate_soroban_auth_function({type, value}) do %__MODULE__{type: type, value: value} end end def new(_value, _opts), do: {:error, :invalid_soroban_auth_function} @impl true def to_xdr(%__MODULE__{type: :contract_fn, value: value}) do type = SorobanAuthorizedFunctionType.new() value |> SorobanAuthorizedContractFunction.to_xdr() |> SorobanAuthorizedFunction.new(type) end def to_xdr(%__MODULE__{type: :create_contract_host_fn, value: value}) do type = SorobanAuthorizedFunctionType.new(:SOROBAN_AUTHORIZED_FUNCTION_TYPE_CREATE_CONTRACT_HOST_FN) value |> CreateContractArgs.to_xdr() |> SorobanAuthorizedFunction.new(type) end def to_xdr(_struct), do: {:error, :invalid_struct} @spec validate_soroban_auth_function(tuple()) :: validation() defp validate_soroban_auth_function( {:contract_fn, %SorobanAuthorizedContractFunction{} = value} ), do: {:ok, value} defp validate_soroban_auth_function({:create_contract_host_fn, %CreateContractArgs{} = value}), do: {:ok, value} defp validate_soroban_auth_function({type, _value}), do: {:error, :"invalid_#{type}"} end