defmodule Soroban.RPC do @moduledoc """ Exposes functions to interact with the Soroban API requests. """ alias Soroban.RPC.{ GetEvents, GetFeeStats, GetHealth, GetLatestLedger, GetLedgerEntries, GetLedgerEntriesResponse, GetNetwork, GetTransaction, GetTransactions, GetVersionInfo, SendTransaction, SimulateTransaction } alias Stellar.TxBuild.LedgerKey alias StellarBase.XDR.LedgerKey, as: LedgerKeyXDR alias StellarBase.XDR.{AccountEntry, LedgerEntryData, SequenceNumber} def fetch_next_sequence_number(server, account_id) do {:account, account_id: account_id} |> LedgerKey.new() |> encode_xdr() |> encode_base64() |> call_get_ledger_entries(server) |> decode_ledger_entry_data() |> increment_sequence_number() end defdelegate send_transaction(server, base64_envelope), to: SendTransaction, as: :request defdelegate simulate_transaction(server, args), to: SimulateTransaction, as: :request defdelegate get_transaction(server, hash), to: GetTransaction, as: :request defdelegate get_transactions(server, payload), to: GetTransactions, as: :request defdelegate get_ledger_entries(server, keys), to: GetLedgerEntries, as: :request defdelegate get_events(server, payload), to: GetEvents, as: :request defdelegate get_health(server), to: GetHealth, as: :request defdelegate get_latest_ledger(server), to: GetLatestLedger, as: :request defdelegate get_network(server), to: GetNetwork, as: :request defdelegate get_fee_stats(server), to: GetFeeStats, as: :request defdelegate get_version_info(server), to: GetVersionInfo, as: :request defp encode_xdr(%LedgerKey{} = ledger_key) do ledger_key |> LedgerKey.to_xdr() |> LedgerKeyXDR.encode_xdr() end defp encode_xdr({:error, reason}), do: {:error, reason} defp encode_base64({:ok, encode_xdr}), do: {:ok, Base.encode64(encode_xdr)} defp encode_base64({:error, reason}), do: {:error, reason} defp call_get_ledger_entries({:ok, ledger_key_base64}, server) do get_ledger_entries(server, [ledger_key_base64]) end defp call_get_ledger_entries({:error, reason}, _server), do: {:error, reason} defp decode_ledger_entry_data( {:ok, %GetLedgerEntriesResponse{entries: [%{xdr: ledger_entry_data_xdr}]}} ) do ledger_entry_data_xdr |> Base.decode64!() |> LedgerEntryData.decode_xdr() end defp decode_ledger_entry_data({:ok, %GetLedgerEntriesResponse{entries: []}}) do {:error, :account_not_found} end defp decode_ledger_entry_data({:error, reason}), do: {:error, reason} defp increment_sequence_number( {:ok, {%LedgerEntryData{ value: %AccountEntry{ seq_num: %SequenceNumber{sequence_number: seq_num} } }, ""}} ) do {:ok, seq_num + 1} end defp increment_sequence_number({:error, reason}), do: {:error, reason} end