Module: OpenReceive::Money

Defined in:
lib/openreceive/core.rb

Class Method Summary collapse

Class Method Details

.bounded_msats(value) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/openreceive/core.rb', line 70

def bounded_msats(value)
  amount = Integer(value)
  unless amount.between?(MIN_AMOUNT_MSATS, MAX_AMOUNT_MSATS)
    raise ArgumentError, "amount_msats is outside the safe range"
  end
  amount
end

.decimal(value, field) ⇒ Object

Raises:

  • (ArgumentError)


78
79
80
81
82
83
84
# File 'lib/openreceive/core.rb', line 78

def decimal(value, field)
  text = value.to_s
  raise ArgumentError, "#{field} must be a positive decimal string" unless /\A[0-9]+(?:\.[0-9]+)?\z/.match?(text)
  parsed = BigDecimal(text)
  raise ArgumentError, "#{field} must be greater than zero" unless parsed.positive?
  parsed
end

.direct_to_msats(currency:, value:) ⇒ Object

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/openreceive/core.rb', line 57

def direct_to_msats(currency:, value:)
  amount = decimal(value, "amount.value")
  sats =
    case currency
    when "BTC" then amount * 100_000_000
    when "SAT", "SATS" then amount
    else raise ArgumentError, "amount.currency must be BTC, SAT, or SATS"
    end
  raise ArgumentError, "amount must resolve to whole satoshis" unless sats.frac.zero?

  bounded_msats(sats.to_i * 1000)
end

.quote_fiat_to_msats(fiat_value:, btc_fiat_price:) ⇒ Object



50
51
52
53
54
55
# File 'lib/openreceive/core.rb', line 50

def quote_fiat_to_msats(fiat_value:, btc_fiat_price:)
  # Bounded like every other amount path (and like the JS quote): a large
  # enough fiat value at a low enough price otherwise produces an
  # amount_msats past the wire contract's 2^53-1 ceiling.
  bounded_msats(quote_fiat_to_sats(fiat_value: fiat_value, btc_fiat_price: btc_fiat_price) * 1000)
end

.quote_fiat_to_sats(fiat_value:, btc_fiat_price:) ⇒ Object

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
# File 'lib/openreceive/core.rb', line 42

def quote_fiat_to_sats(fiat_value:, btc_fiat_price:)
  fiat = decimal(fiat_value, "fiat.value")
  price = decimal(btc_fiat_price, "btc_fiat_price")
  raise ArgumentError, "btc_fiat_price must be greater than zero" unless price.positive?

  ((fiat * 100_000_000) / price).ceil
end