class ExoCrypto::CryptoCalc

Public Class Methods

apply_fun(f, args) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 80
def self.apply_fun(f, args)
  args_prime = args.map { |i| BigDecimal(i) }

  lambdas = {
    'fst'         => lambda { |args| args[0] },
    '1/fst'       => lambda { |args| 1.0 / args[0] },
    'fst,snd'     => lambda { |args| [args[0], args[1]] },
    'fst*snd'     => lambda { |args| args[0] * args[1] },
    'fst/snd'     => lambda { |args| args[0] / args[1] },
    'snd/fst'     => lambda { |args| args[1] / args[0] },
    '1/(fst*snd)' => lambda { |args| 1.0 / (args[0] * args[1]) },
  }

  lambdas[f].call(args_prime)
end
do_partial_payments(request, payments) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 37
def self.do_partial_payments(request, payments)
  epoch = ExoBasic::Timer::EPOCH.to_datetime
  xs = payments.map do |payment|
    if payment[:paid]
      precision = Bip44WalletProvider.precision_of(payment[:currency])
      satoshis  = BigDecimal(payment[:amount_paid]) * BigDecimal(payment[:exchange_rate])

      [satoshis / BigDecimal(10 ** precision), payment[:date]]
    else
      [BigDecimal(0), epoch]
    end
  end
  total_paid = xs.map { |x| x[0] }.sum
  paid_date  = xs.map { |x| x[1] }.max
  if paid_date == epoch
    paid_date = nil
  end
  request_amount       = request[:amount]
  request_precision    = request[:precision]
  total_paid_rounded_s = CryptoCalc.fixed_length_to_s(total_paid.round(request_precision),
                                                      request_precision)
  remaining            = BigDecimal(request[:amount]) - BigDecimal(total_paid_rounded_s)
  remaining_rounded_s  = CryptoCalc.fixed_length_to_s(remaining.round(request_precision),
                                                      request_precision)
  n_paid               = payments.select { |payment| payment[:paid] == true }.length
  n_unpaid             = payments.length - n_paid
  remaining_rounded    = BigDecimal(remaining_rounded_s)
  needs_change         = remaining_rounded < BigDecimal(0)
  is_fully_paid        = remaining_rounded.zero? || needs_change
  is_partially_paid    = !is_fully_paid && remaining_rounded < BigDecimal(request_amount)

  {
    :n_paid => n_paid,
    :n_unpaid => n_unpaid,
    :paid_date => paid_date,
    :amount_paid => total_paid_rounded_s,
    :amount_remaining => remaining_rounded_s,
    :overpaid => needs_change,
    :is_fully_paid => is_fully_paid,
    :is_partially_paid => is_partially_paid
  }
end
fixed_length_to_s(amount, precision) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 15
def self.fixed_length_to_s(amount, precision)
  "%.#{precision}f" % amount
end
get_satoshis(currency, exchange_rate, remaining) click to toggle source

see: reinteractive.com/posts/373-diving-into-the-ruby-source-code-bigdecimal-rounding-options

# File lib/exocrypto/crypto_calc.rb, line 25
def self.get_satoshis(currency, exchange_rate, remaining)
  precision         = Bip44WalletProvider.precision_of(currency)
  amount_to_be_paid = 0
  rate              = BigDecimal(exchange_rate)
  if !rate.zero?
    amount_to_be_paid = BigDecimal(remaining) / rate
    amount_to_be_paid = (amount_to_be_paid.round(precision) * BigDecimal(10 ** precision)).to_i
  end

  amount_to_be_paid
end
mul(a, b) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 3
def self.mul(a, b)
  BigDecimal(a) * BigDecimal(b)
end
s_from_satoshis(amount, precision) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 11
def self.s_from_satoshis(amount, precision)
  (amount / BigDecimal(10 ** precision)).to_s
end
s_to_satoshis(amount, precision) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 7
def self.s_to_satoshis(amount, precision)
  (BigDecimal(amount) * BigDecimal(10 ** precision)).to_i
end
to_fixed_length(amount, currency) click to toggle source
# File lib/exocrypto/crypto_calc.rb, line 19
def self.to_fixed_length(amount, currency)
  precision = Bip44WalletProvider.precision_of(currency)
  CryptoCalc.fixed_length_to_s(CryptoCalc.s_from_satoshis(amount, precision), precision)
end