Module: MixinBot::Utils::Amount
- Included in:
- MixinBot::Utils
- Defined in:
- lib/mixin_bot/utils/amount.rb
Overview
Decimal-safe unit conversion between human-readable amounts and decimal strings, mirroring the Node SDK's utils/amount.ts (BigNumber-based).
Constant Summary collapse
- DECIMAL_STRING_PATTERN =
/\A[+-]?\d+(\.\d+)?\z/
Instance Method Summary collapse
-
#format_units(amount, decimals) ⇒ Object
Divide an amount by 10**decimals and return the exact decimal string.
-
#parse_units(amount, decimals) ⇒ Object
Multiply a decimal amount string by 10**decimals and return integer minor units.
Instance Method Details
#format_units(amount, decimals) ⇒ Object
Divide an amount by 10decimals and return the exact decimal string. Accepts Integers and decimal strings ('7.5'); leading zeros are decimal, never octal. Mirrors BigNumber(amount).dividedBy(10unit).
MixinBot.utils.format_units(10**17, 18) # => "0.1"
MixinBot.utils.format_units('010', 18) # => "0.00000000000000001"
MixinBot.utils.format_units('7.5', 2) # => "0.075"
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/mixin_bot/utils/amount.rb', line 23 def format_units(amount, decimals) decimals = validated_decimals(decimals) value = validated_amount_string(amount) sign = value.start_with?('-') ? '-' : '' whole, fraction = value.delete_prefix('-').delete_prefix('+').split('.') fraction ||= '' digits = "#{whole}#{fraction}".sub(/\A0+(?=\d)/, '') shift = fraction.length + decimals formatted = if shift.zero? digits elsif digits.size > shift "#{digits[0...-shift]}.#{digits[-shift..]}" else "0.#{'0' * (shift - digits.size)}#{digits}" end "#{sign}#{formatted}".sub(/(\.\d*?)0+\z/, '\1').sub(/\.\z/, '') end |
#parse_units(amount, decimals) ⇒ Object
52 53 54 55 56 57 |
# File 'lib/mixin_bot/utils/amount.rb', line 52 def parse_units(amount, decimals) decimals = validated_decimals(decimals) value = validated_amount_string(amount) (value.to_d * (10**decimals)).floor end |