Module: Webcash::Helpers
- Defined in:
- lib/webcash/helpers.rb
Overview
Provides helper methods for Webcash.
Class Method Summary collapse
- .assert_is_array(input) ⇒ Object
- .chunk_array(array, chunk_size) ⇒ Object
- .convert_secret_hex_to_bytes(secret) ⇒ Object
- .convert_secret_value_to_public_value(secret_value) ⇒ Object
- .create_webcash_with_random_secret_from_amount(amount) ⇒ Object
-
.decimal_amount_to_string(amount) ⇒ Object
Convert a decimal amount to a string.
- .deserialize_webcash(webcash) ⇒ Object
- .generate_random_value(length) ⇒ Object
- .hex_to_bytes(hex) ⇒ Object
- .hex_to_padded_bytes(hex, padding_target_length = 32) ⇒ Object
- .long_to_byte_array(num) ⇒ Object
- .padded_bytes(bytes, padding_target_length = 32) ⇒ Object
- .parse_amount_from_string(amount_raw) ⇒ Object
- .range(start, stop, step = 1) ⇒ Object
- .sha256_from_array(array) ⇒ Object
-
.string_amount_to_decimal(amount) ⇒ Object
Convert from a string amount to a Decimal value.
-
.validate_amount_decimals(amount) ⇒ Object
Check that the amount has no more than a maximum number of decimal places.
Class Method Details
.assert_is_array(input) ⇒ Object
158 159 160 161 162 |
# File 'lib/webcash/helpers.rb', line 158 def self.assert_is_array(input) unless input.is_a?(Array) && input.all? { |e| e.is_a?(Integer) } raise "This method only supports number arrays but input was: #{input}" end end |
.chunk_array(array, chunk_size) ⇒ Object
25 26 27 |
# File 'lib/webcash/helpers.rb', line 25 def self.chunk_array(array, chunk_size) array.each_slice(chunk_size).to_a end |
.convert_secret_hex_to_bytes(secret) ⇒ Object
127 128 129 |
# File 'lib/webcash/helpers.rb', line 127 def self.convert_secret_hex_to_bytes(secret) hex_to_padded_bytes(secret) end |
.convert_secret_value_to_public_value(secret_value) ⇒ Object
92 93 94 |
# File 'lib/webcash/helpers.rb', line 92 def self.convert_secret_value_to_public_value(secret_value) Digest::SHA256.hexdigest(secret_value) end |
.create_webcash_with_random_secret_from_amount(amount) ⇒ Object
117 118 119 |
# File 'lib/webcash/helpers.rb', line 117 def self.create_webcash_with_random_secret_from_amount(amount) "e#{amount.to_s('F')}:secret:#{generate_random_value(32)}" end |
.decimal_amount_to_string(amount) ⇒ Object
Convert a decimal amount to a string. This is used for representing different webcash when serializing webcash. When the amount is not known, the string should be “?”.
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/webcash/helpers.rb', line 105 def self.decimal_amount_to_string(amount) return "?" if amount.nil? if amount.frac.zero? amount.to_i.to_s else # Force 8 decimals and trim trailing zeros amount_str = format("%.8f", amount) amount_str.sub(/\.?0+$/, "") end end |
.deserialize_webcash(webcash) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/webcash/helpers.rb', line 44 def self.deserialize_webcash(webcash) raise Error, "Unusable format for webcash." unless webcash.include?(":") parts = webcash.split(":") raise Error, "Don't know how to deserialize this webcash." if parts.length < 2 amount_raw = parts[0] public_or_secret = parts[1] value = parts[2] raise Error, "Can't deserialize this webcash, value is missing." if value.nil? unless %w[public secret].include?(public_or_secret) raise Error, "Can't deserialize this webcash, needs to be either public/secret." end amount = parse_amount_from_string(amount_raw) if public_or_secret == "secret" Webcash::Secret.new(amount, value) else Webcash::Public.new(amount, value) end end |
.generate_random_value(length) ⇒ Object
174 175 176 |
# File 'lib/webcash/helpers.rb', line 174 def self.generate_random_value(length) (1..length).map { rand(16).to_s(16) }.join end |
.hex_to_bytes(hex) ⇒ Object
131 132 133 134 |
# File 'lib/webcash/helpers.rb', line 131 def self.hex_to_bytes(hex) hex = hex.sub(/^0x/i, "") hex.scan(/../).map { |x| x.hex } end |
.hex_to_padded_bytes(hex, padding_target_length = 32) ⇒ Object
121 122 123 124 125 |
# File 'lib/webcash/helpers.rb', line 121 def self.hex_to_padded_bytes(hex, padding_target_length = 32) bytes = [ hex.sub(/^0x/, "") ].pack("H*").bytes padded_bytes = Array.new(padding_target_length - bytes.length, 0) + bytes padded_bytes end |
.long_to_byte_array(num) ⇒ Object
147 148 149 150 151 152 153 154 155 156 |
# File 'lib/webcash/helpers.rb', line 147 def self.long_to_byte_array(num) byte_array = Array.new(8, 0) (0...byte_array.length).each do |index| byte_array[index] = num & 0xff num >>= 8 end byte_array end |
.padded_bytes(bytes, padding_target_length = 32) ⇒ Object
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/webcash/helpers.rb', line 136 def self.padded_bytes(bytes, padding_target_length = 32) if bytes.length == padding_target_length bytes elsif bytes.length > padding_target_length raise "Can only handle up to #{padding_target_length} bytes, int too big to convert" else padding_needed = padding_target_length - bytes.length Array.new(padding_needed, 0) + bytes end end |
.parse_amount_from_string(amount_raw) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/webcash/helpers.rb', line 69 def self.parse_amount_from_string(amount_raw) # If there is a colon in the value, then the amount is going to be on the # left hand side. part1 = amount_raw.split(":")[0] # There can be at most one 'e' in the value, at the beginning. count = part1.count("e") if count.zero? BigDecimal(part1) elsif count <= 1 # should be at the beginning raise Error, "Invalid amount format for webcash." unless part1[0] == "e" # there needs to be an actual amount raise Error, "Invalid amount format for webcash." unless part1 != "e" part2 = part1.split("e")[1] BigDecimal(part2) else raise Error, "Invalid amount format for webcash." end end |
.range(start, stop, step = 1) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/webcash/helpers.rb', line 12 def self.range(start, stop, step = 1) return [] if (step.positive? && start >= stop) || (step.negative? && start <= stop) result = [] i = start while step.positive? ? i < stop : i > stop result << i i += step end result end |
.sha256_from_array(array) ⇒ Object
164 165 166 167 168 169 170 171 172 |
# File 'lib/webcash/helpers.rb', line 164 def self.sha256_from_array(array) assert_is_array(array) # Convert the array of integers to a binary string binary_string = array.pack("C*") # Create and return the SHA256 digest Digest::SHA256.digest(binary_string) end |
.string_amount_to_decimal(amount) ⇒ Object
Convert from a string amount to a Decimal value.
97 98 99 |
# File 'lib/webcash/helpers.rb', line 97 def self.string_amount_to_decimal(amount) BigDecimal(amount) end |
.validate_amount_decimals(amount) ⇒ Object
Check that the amount has no more than a maximum number of decimal places.
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/webcash/helpers.rb', line 30 def self.validate_amount_decimals(amount) if amount.is_a?(String) amount = parse_amount_from_string(amount) elsif amount.is_a?(Float) amount = BigDecimal(amount.to_s) else amount = BigDecimal(amount) end raise RangeError, "Amount precision should be at most 8 decimals." unless amount.scale <= 8 true end |