Packages
stellar_sdk
0.15.1
0.23.0
0.22.0
0.21.2
0.21.1
0.21.0
0.20.0
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.1
0.13.0
0.12.0
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Elixir SDK for the Stellar network.
Current section
Files
Jump to
Current section
Files
lib/tx_build/host_function.ex
defmodule Stellar.TxBuild.HostFunction do
@moduledoc """
`HostFunction` struct definition.
"""
alias Stellar.TxBuild.{ContractAuth, HostFunctionArgs}
alias StellarBase.XDR.ContractAuthList
alias StellarBase.XDR.ContractAuth, as: ContractAuthXDR
alias StellarBase.XDR.HostFunction, as: HostFunctionXDR
@behaviour Stellar.TxBuild.XDR
@type args :: HostFunctionArgs.t()
@type contract_auth :: ContractAuth.t()
@type contract_auth_xdr :: ContractAuthXDR.t()
@type auth :: list(contract_auth()) | list(String.t())
@type error :: {:error, atom()}
@type validation :: {:ok, any()} | error()
@type t :: %__MODULE__{
args: args(),
auth: auth()
}
defstruct [:args, :auth]
@impl true
def new(args, opts \\ [])
def new(args, _opts) when is_list(args) do
function_args = Keyword.get(args, :args)
auth = Keyword.get(args, :auth, [])
with {:ok, args} <- validate_host_function_args(function_args),
{:ok, auth} <- validate_host_function_auth(auth) do
%__MODULE__{args: args, auth: auth}
end
end
def new(_args, _opts), do: {:error, :invalid_operation_attributes}
@impl true
def to_xdr(%__MODULE__{
args: args,
auth: [%ContractAuth{} | _] = auth
})
when is_list(auth) do
args_xdr = HostFunctionArgs.to_xdr(args)
contract_auth =
auth
|> Enum.map(&ContractAuth.to_xdr/1)
|> ContractAuthList.new()
HostFunctionXDR.new(args_xdr, contract_auth)
end
def to_xdr(%__MODULE__{
args: args,
auth: auth
})
when is_list(auth) do
args_xdr = HostFunctionArgs.to_xdr(args)
contract_auth =
auth
|> Enum.map(&decode_contract_auth/1)
|> ContractAuthList.new()
HostFunctionXDR.new(args_xdr, contract_auth)
end
@spec set_auth(module :: t(), auth :: auth()) :: t() | error()
def set_auth(%__MODULE__{} = module, auth) when is_list(auth) do
with {:ok, auth} <- validate_auth_strings(auth) do
%{module | auth: auth}
end
end
defp validate_auth_strings(auth) do
if Enum.all?(auth, &validate_xdr_string/1),
do: {:ok, auth},
else: {:error, :invalid_auth}
end
@spec validate_xdr_string(xdr :: String.t() | nil) :: boolean()
defp validate_xdr_string(nil), do: true
defp validate_xdr_string(xdr) when is_binary(xdr) do
case Base.decode64(xdr) do
{:ok, _} -> true
:error -> false
end
end
@spec validate_host_function_args(args :: args()) :: validation()
defp validate_host_function_args(%HostFunctionArgs{} = args), do: {:ok, args}
defp validate_host_function_args(_args), do: {:error, :invalid_args}
@spec validate_host_function_auth(auth :: auth()) :: validation()
defp validate_host_function_auth(auth) do
if Enum.all?(auth, &is_contract_auth?/1),
do: {:ok, auth},
else: {:error, :invalid_auth}
end
@spec is_contract_auth?(contract_auth :: contract_auth()) :: boolean()
defp is_contract_auth?(%ContractAuth{}), do: true
defp is_contract_auth?(_arg), do: false
@spec decode_contract_auth(auth :: String.t()) :: contract_auth_xdr()
defp decode_contract_auth(auth) do
{contract_auth, ""} =
auth
|> Base.decode64!()
|> ContractAuthXDR.decode_xdr!()
contract_auth
end
end