defmodule Stellar.TxBuild.SCAddress do
@moduledoc """
`SCAddress` struct definition.
"""
@behaviour Stellar.TxBuild.XDR
alias Stellar.KeyPair
alias StellarBase.XDR.{
SCAddressType,
Hash,
SCAddress
}
alias Stellar.TxBuild.AccountID
@type validation :: {:ok, any()} | {:error, atom()}
@type value :: binary()
@type t :: %__MODULE__{
type: atom(),
value: value()
}
defstruct [:type, :value]
@impl true
def new(args, opts \\ nil)
def new(value, _opts) do
with {:ok, {type, value}} <- validate_sc_address(value) do
%__MODULE__{
type: type,
value: value
}
end
end
@impl true
def to_xdr(%__MODULE__{type: :account, value: value}) do
type = SCAddressType.new(:SC_ADDRESS_TYPE_ACCOUNT)
value
|> AccountID.new()
|> AccountID.to_xdr()
|> SCAddress.new(type)
end
def to_xdr(%__MODULE__{type: :contract, value: value}) do
type = SCAddressType.new(:SC_ADDRESS_contract)
value
|> Hash.new()
|> SCAddress.new(type)
end
@spec validate_sc_address(value :: binary()) :: validation()
defp validate_sc_address(value) when is_binary(value) do
cond do
KeyPair.validate_public_key(value) == :ok -> {:ok, {:account, value}}
KeyPair.validate_contract(value) == :ok -> {:ok, {:contract, value}}
true -> {:error, :invalid_sc_address}
end
end
defp validate_sc_address(_value), do: {:error, :invalid_sc_address}
end