defmodule Stellar.TxBuild.CreateClaimableBalance do
@moduledoc """
`CreateClaimableBalance` struct definition.
"""
import Stellar.TxBuild.Validations,
only: [validate_asset: 1, validate_amount: 1, validate_optional_account: 1]
alias Stellar.TxBuild.{Amount, Asset, Claimants, OptionalAccount}
alias StellarBase.XDR.{OperationBody, OperationType, Operations.CreateClaimableBalance}
@type validation :: {:ok, any()} | {:error, atom()}
@behaviour Stellar.TxBuild.XDR
@type t :: %__MODULE__{
asset: Asset.t(),
amount: Amount.t(),
claimants: Claimants.t(),
source_account: OptionalAccount.t()
}
defstruct [:asset, :amount, :claimants, :source_account]
@impl true
def new(args, opts \\ [])
def new(args, _opts) when is_list(args) do
asset = Keyword.get(args, :asset)
amount = Keyword.get(args, :amount)
claimants = Keyword.get(args, :claimants)
source_account = Keyword.get(args, :source_account)
with {:ok, asset} <- validate_asset({:asset, asset}),
{:ok, amount} <- validate_amount({:amount, amount}),
{:ok, claimants} <- validate_claimants(claimants),
{:ok, source_account} <- validate_optional_account({:source_account, source_account}) do
%__MODULE__{
asset: asset,
amount: amount,
claimants: claimants,
source_account: source_account
}
end
end
def new(_args, _opts), do: {:error, :invalid_operation_attributes}
@impl true
def to_xdr(%__MODULE__{
asset: asset,
amount: amount,
claimants: claimants
}) do
op_type = OperationType.new(:CREATE_CLAIMABLE_BALANCE)
asset = Asset.to_xdr(asset)
amount = Amount.to_xdr(amount)
claimants = Claimants.to_xdr(claimants)
claimable_balance =
CreateClaimableBalance.new(
asset,
amount,
claimants
)
OperationBody.new(claimable_balance, op_type)
end
@spec validate_claimants(claimants :: Claimants.t()) :: validation()
defp validate_claimants(claimants) do
case claimants do
%Claimants{} = claimants -> {:ok, claimants}
_error -> {:error, :invalid_claimant_list}
end
end
end