Packages

A User-Friendly Component-Based Cardano SDK for Elixir.

Current section

Files

Jump to
sutra_cardano lib sutra cardano transaction tx_builder tx_config.ex
Raw

lib/sutra/cardano/transaction/tx_builder/tx_config.ex

defmodule Sutra.Cardano.Transaction.TxBuilder.TxConfig do
@moduledoc """
Transaction Config
"""
alias Sutra.Cardano.Address
alias Sutra.Cardano.Transaction.TxBuilder.Error.ConfigError
alias Sutra.ProtocolParams
alias Sutra.Provider
alias Sutra.SlotConfig
alias Sutra.Utils
import Sutra.Utils, only: [maybe: 2]
defstruct protocol_params: nil,
wallet_address: nil,
change_address: nil,
change_datum: nil,
provider: nil,
slot_config: nil,
evaluate_provider_uplc: false,
debug: false
def __override_cfg(%__MODULE__{} = cfg, _, nil), do: cfg
def __override_cfg(%__MODULE__{} = cfg, key, value), do: Map.put_new(cfg, key, value)
def __set_cfg(%__MODULE__{} = cfg, key, value), do: Map.put(cfg, key, value)
# credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity
def __setup(%__MODULE__{} = cfg, opts \\ []) do
Enum.reduce(opts, cfg, fn curr_opt, %__MODULE__{} = acc ->
case curr_opt do
{_, nil} ->
acc
{_, []} ->
acc
{:slot_config, %SlotConfig{} = slot_cfg} ->
%__MODULE__{acc | slot_config: slot_cfg}
{:protocol_params, %ProtocolParams{} = v} ->
%__MODULE__{acc | protocol_params: v}
{:provider, v} ->
%__MODULE__{acc | provider: v}
{:wallet_address, addresses} when is_list(addresses) ->
%__MODULE__{acc | wallet_address: Enum.map(addresses, &parse_address/1)}
{:wallet_address, address} ->
%__MODULE__{acc | wallet_address: [parse_address(address)]}
{:change_address, %Address{} = address} ->
%__MODULE__{acc | change_address: address}
{:change_address, address} when is_binary(address) ->
%__MODULE__{acc | change_address: Address.from_bech32(address)}
{:evaluate_provider_uplc, v} when is_boolean(v) ->
%__MODULE__{acc | evaluate_provider_uplc: v}
_ ->
acc
end
end)
end
defp parse_address(%Address{} = addr), do: addr
defp parse_address(bech_32_addr) when is_binary(bech_32_addr),
do: Address.from_bech32(bech_32_addr)
@doc """
Setup Wallet Utxos, protocol_params if not setup manually
"""
def __init(%__MODULE__{provider: nil} = cfg) do
case Provider.get_fetcher() do
{:ok, provider} ->
__init(%__MODULE__{cfg | provider: provider})
_ ->
cfg
end
end
def __init(%__MODULE__{} = cfg) do
Enum.reduce(Map.from_struct(cfg), cfg, fn cfg_field, %__MODULE__{} = acc ->
case cfg_field do
{:wallet_address, wallet_addrs} when is_list(wallet_addrs) ->
%__MODULE__{
acc
| change_address: maybe(cfg.change_address, Utils.safe_head(wallet_addrs))
}
{:change_address, %Address{} = change_address} ->
%__MODULE__{acc | change_address: change_address}
{:provider, provider} when not is_nil(provider) ->
%__MODULE__{
acc
| protocol_params: maybe(cfg.protocol_params, fn -> provider.protocol_params() end),
slot_config: maybe(cfg.slot_config, provider.slot_config())
}
_ ->
acc
end
end)
end
def validate(%__MODULE__{} = cfg) do
cond do
is_nil(cfg.provider) ->
{:error, %ConfigError{reason: "Provider Not Set"}}
not Utils.instance_of?(cfg.change_address, Address) ->
{:error, %ConfigError{reason: "Change Address not Available"}}
not Utils.instance_of?(cfg.protocol_params, ProtocolParams) ->
{:error, %ConfigError{reason: "Protocol params Missing"}}
not Utils.instance_of?(cfg.slot_config, SlotConfig) ->
{:error, %ConfigError{reason: "Slot Config missing"}}
true ->
{:ok, cfg}
end
end
end