Packages

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

Current section

Files

Jump to
sutra_cardano lib sutra provider koios koios.ex
Raw

lib/sutra/provider/koios/koios.ex

defmodule Sutra.Provider.Koios do
@moduledoc """
Koios Provider implementation.
"""
@behaviour Sutra.Provider
alias Sutra.Cardano.Transaction
alias Sutra.Cardano.Transaction.{Datum, Input, Output}
alias Sutra.Data
alias Sutra.Provider.Koios.Client
alias Sutra.SlotConfig
alias Sutra.Utils
defp fetch_env(key), do: Application.get_env(:sutra, :koios)[key]
defp client do
Client.new(network: network(), api_key: fetch_env(:api_key))
end
@impl true
def network, do: fetch_env(:network) || :mainnet
@impl true
def utxos_at_addresses(addresses) do
client()
|> Client.utxos_at_addresses(addresses)
|> attach_datum_raw_to_utxos()
end
@impl true
def utxos_at_tx_refs(refs) do
client()
|> Client.utxos_at_tx_refs(refs)
|> attach_datum_raw_to_utxos()
end
@impl true
def datum_of(datum_hashes) do
client()
|> Client.datum_of(datum_hashes)
end
@impl true
def protocol_params do
client()
|> Client.protocol_params()
end
@impl true
def slot_config do
network()
|> SlotConfig.fetch_slot_config()
end
@impl true
def submit_tx(cbor) when is_binary(cbor) do
client()
|> Client.submit_tx(cbor)
end
def submit_tx(%Transaction{} = tx) do
Transaction.to_cbor(tx)
|> CBOR.encode()
|> submit_tx()
end
@impl true
def tx_cbor(tx_hashes) do
client()
|> Client.tx_cbor(tx_hashes)
end
# Internal Logic
defp attach_datum_raw_to_utxos(utxos) when is_list(utxos) do
get_datum_hash = fn %Output{datum: %Datum{} = datum} ->
if datum.kind == :datum_hash, do: datum.value, else: nil
end
datum_hashes =
Enum.reduce(utxos, MapSet.new([]), fn %Input{output: %Output{} = o}, acc ->
Utils.maybe(get_datum_hash.(o), acc, &MapSet.put(acc, &1))
end)
|> MapSet.to_list()
|> datum_of()
put_raw_datum = fn %Output{} = output ->
Utils.maybe(get_datum_hash.(output), output, fn hash ->
%Output{
output
| datum_raw: Utils.maybe(datum_hashes[hash], nil, &Data.decode!/1)
}
end)
end
if datum_hashes == %{},
do: utxos,
else:
Enum.map(utxos, fn %Input{output: %Output{}} = input ->
%Input{input | output: put_raw_datum.(input.output)}
end)
end
end