defmodule Stellar.TxBuild.HashIDPreimage do
@moduledoc """
`HashIDPreimage` struct definition.
"""
alias StellarBase.XDR.{EnvelopeType, HashIDPreimage}
alias Stellar.TxBuild.{
HashIDPreimageContractID,
HashIDPreimageSorobanAuthorization,
HashIDPreimageOperationID,
HashIDPreimageRevokeID
}
@behaviour Stellar.TxBuild.XDR
@type hash_id ::
HashIDPreimageContractID.t()
| HashIDPreimageOperationID.t()
| HashIDPreimageRevokeID.t()
| HashIDPreimageSorobanAuthorization.t()
@type validation :: {:ok, any()} | {:error, atom()}
@type type ::
:op_id
| :pool_revoke_op_id
| :contract_id
| :soroban_auth
@type t :: %__MODULE__{type: type(), value: hash_id()}
defstruct [:type, :value]
@allowed_types ~w(op_id pool_revoke_op_id contract_id soroban_auth)a
@impl true
def new(args, opts \\ nil)
def new([{type, value}], _opts) when type in @allowed_types do
with {:ok, value} <- validate_hash_id_preimage({type, value}) do
%__MODULE__{
type: type,
value: value
}
end
end
def new(_args, _opts), do: {:error, :invalid_hash_id_preimage_type}
@impl true
def to_xdr(%__MODULE__{
type: :op_id,
value: %HashIDPreimageOperationID{} = value
}) do
envelope_type = EnvelopeType.new(:ENVELOPE_TYPE_OP_ID)
value
|> HashIDPreimageOperationID.to_xdr()
|> HashIDPreimage.new(envelope_type)
end
def to_xdr(%__MODULE__{
type: :pool_revoke_op_id,
value: %HashIDPreimageRevokeID{} = value
}) do
envelope_type = EnvelopeType.new(:ENVELOPE_TYPE_POOL_REVOKE_OP_ID)
value
|> HashIDPreimageRevokeID.to_xdr()
|> HashIDPreimage.new(envelope_type)
end
def to_xdr(%__MODULE__{
type: :contract_id,
value: %HashIDPreimageContractID{} = value
}) do
envelope_type = EnvelopeType.new(:ENVELOPE_TYPE_CONTRACT_ID)
value
|> HashIDPreimageContractID.to_xdr()
|> HashIDPreimage.new(envelope_type)
end
def to_xdr(%__MODULE__{
type: :soroban_auth,
value: %HashIDPreimageSorobanAuthorization{} = value
}) do
envelope_type = EnvelopeType.new(:ENVELOPE_TYPE_SOROBAN_AUTHORIZATION)
value
|> HashIDPreimageSorobanAuthorization.to_xdr()
|> HashIDPreimage.new(envelope_type)
end
@spec validate_hash_id_preimage({atom(), hash_id()}) :: validation()
defp validate_hash_id_preimage({:op_id, %HashIDPreimageOperationID{} = value}), do: {:ok, value}
defp validate_hash_id_preimage({:pool_revoke_op_id, %HashIDPreimageRevokeID{} = value}),
do: {:ok, value}
defp validate_hash_id_preimage({:contract_id, %HashIDPreimageContractID{} = value}),
do: {:ok, value}
defp validate_hash_id_preimage({:soroban_auth, %HashIDPreimageSorobanAuthorization{} = value}),
do: {:ok, value}
defp validate_hash_id_preimage({type, _value}), do: {:error, :"invalid_#{type}"}
end