auction-ruby-base 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +8 -0
  5. data/CHANGELOG.md +58 -0
  6. data/CONTRIBUTING.md +48 -0
  7. data/Gemfile +15 -0
  8. data/Guardfile +5 -0
  9. data/LICENSE.txt +202 -0
  10. data/README.md +83 -0
  11. data/Rakefile +4 -0
  12. data/auction-ruby-base.gemspec +35 -0
  13. data/examples/create_account.rb +26 -0
  14. data/examples/low_level_transaction_post.rb +46 -0
  15. data/examples/mid_level_transaction_post.rb +33 -0
  16. data/examples/non_native_payment.rb +60 -0
  17. data/examples/offer.rb +75 -0
  18. data/examples/transaction_merge.rb +23 -0
  19. data/generated/stellar-base-generated.rb +174 -0
  20. data/generated/stellar/account_entry.rb +55 -0
  21. data/generated/stellar/account_entry/ext.rb +24 -0
  22. data/generated/stellar/account_flags.rb +31 -0
  23. data/generated/stellar/account_merge_result.rb +26 -0
  24. data/generated/stellar/account_merge_result_code.rb +30 -0
  25. data/generated/stellar/affirm_fail_op.rb +22 -0
  26. data/generated/stellar/affirm_fail_result.rb +25 -0
  27. data/generated/stellar/affirm_fail_result_code.rb +22 -0
  28. data/generated/stellar/affirm_pass_op.rb +24 -0
  29. data/generated/stellar/affirm_pass_result.rb +25 -0
  30. data/generated/stellar/affirm_pass_result_code.rb +22 -0
  31. data/generated/stellar/allow_trust_op.rb +38 -0
  32. data/generated/stellar/allow_trust_op/asset.rb +33 -0
  33. data/generated/stellar/allow_trust_result.rb +25 -0
  34. data/generated/stellar/allow_trust_result_code.rb +31 -0
  35. data/generated/stellar/asset.rb +47 -0
  36. data/generated/stellar/asset/alpha_num12.rb +22 -0
  37. data/generated/stellar/asset/alpha_num4.rb +22 -0
  38. data/generated/stellar/asset_type.rb +24 -0
  39. data/generated/stellar/auth.rb +20 -0
  40. data/generated/stellar/auth_cert.rb +22 -0
  41. data/generated/stellar/authenticated_message.rb +32 -0
  42. data/generated/stellar/authenticated_message/v0.rb +24 -0
  43. data/generated/stellar/bucket_entry.rb +28 -0
  44. data/generated/stellar/bucket_entry_type.rb +22 -0
  45. data/generated/stellar/change_trust_op.rb +22 -0
  46. data/generated/stellar/change_trust_result.rb +25 -0
  47. data/generated/stellar/change_trust_result_code.rb +31 -0
  48. data/generated/stellar/claim_offer_atom.rb +33 -0
  49. data/generated/stellar/create_account_op.rb +20 -0
  50. data/generated/stellar/create_account_result.rb +25 -0
  51. data/generated/stellar/create_account_result_code.rb +32 -0
  52. data/generated/stellar/create_bid_op.rb +20 -0
  53. data/generated/stellar/create_bid_result.rb +25 -0
  54. data/generated/stellar/create_bid_result_code.rb +22 -0
  55. data/generated/stellar/create_lot_op.rb +46 -0
  56. data/generated/stellar/create_lot_result.rb +25 -0
  57. data/generated/stellar/create_lot_result_code.rb +22 -0
  58. data/generated/stellar/create_passive_offer_op.rb +24 -0
  59. data/generated/stellar/crypto_key_type.rb +20 -0
  60. data/generated/stellar/curve25519_public.rb +18 -0
  61. data/generated/stellar/curve25519_secret.rb +18 -0
  62. data/generated/stellar/decorated_signature.rb +20 -0
  63. data/generated/stellar/dont_have.rb +20 -0
  64. data/generated/stellar/envelope_type.rb +24 -0
  65. data/generated/stellar/error.rb +20 -0
  66. data/generated/stellar/error_code.rb +28 -0
  67. data/generated/stellar/hello.rb +34 -0
  68. data/generated/stellar/hmac_sha256_key.rb +18 -0
  69. data/generated/stellar/hmac_sha256_mac.rb +18 -0
  70. data/generated/stellar/inflation_payout.rb +20 -0
  71. data/generated/stellar/inflation_result.rb +26 -0
  72. data/generated/stellar/inflation_result_code.rb +24 -0
  73. data/generated/stellar/ip_addr_type.rb +22 -0
  74. data/generated/stellar/ledger_entry.rb +52 -0
  75. data/generated/stellar/ledger_entry/data.rb +49 -0
  76. data/generated/stellar/ledger_entry/ext.rb +24 -0
  77. data/generated/stellar/ledger_entry_change.rb +35 -0
  78. data/generated/stellar/ledger_entry_change_type.rb +26 -0
  79. data/generated/stellar/ledger_entry_type.rb +32 -0
  80. data/generated/stellar/ledger_header.rb +69 -0
  81. data/generated/stellar/ledger_header/ext.rb +24 -0
  82. data/generated/stellar/ledger_header_history_entry.rb +33 -0
  83. data/generated/stellar/ledger_header_history_entry/ext.rb +24 -0
  84. data/generated/stellar/ledger_key.rb +87 -0
  85. data/generated/stellar/ledger_key/account.rb +20 -0
  86. data/generated/stellar/ledger_key/lot.rb +22 -0
  87. data/generated/stellar/ledger_key/message.rb +22 -0
  88. data/generated/stellar/ledger_key/offer.rb +22 -0
  89. data/generated/stellar/ledger_key/participant.rb +22 -0
  90. data/generated/stellar/ledger_key/proof.rb +22 -0
  91. data/generated/stellar/ledger_key/trust_line.rb +22 -0
  92. data/generated/stellar/ledger_scp_messages.rb +20 -0
  93. data/generated/stellar/ledger_upgrade.rb +31 -0
  94. data/generated/stellar/ledger_upgrade_type.rb +24 -0
  95. data/generated/stellar/lot_branch.rb +21 -0
  96. data/generated/stellar/lot_entry.rb +64 -0
  97. data/generated/stellar/lot_entry/ext.rb +24 -0
  98. data/generated/stellar/lot_type.rb +21 -0
  99. data/generated/stellar/manage_offer_effect.rb +24 -0
  100. data/generated/stellar/manage_offer_op.rb +28 -0
  101. data/generated/stellar/manage_offer_result.rb +26 -0
  102. data/generated/stellar/manage_offer_result_code.rb +50 -0
  103. data/generated/stellar/manage_offer_success_result.rb +34 -0
  104. data/generated/stellar/manage_offer_success_result/offer.rb +30 -0
  105. data/generated/stellar/memo.rb +38 -0
  106. data/generated/stellar/memo_type.rb +28 -0
  107. data/generated/stellar/message_entry.rb +38 -0
  108. data/generated/stellar/message_entry/ext.rb +24 -0
  109. data/generated/stellar/message_type.rb +51 -0
  110. data/generated/stellar/offer_entry.rb +49 -0
  111. data/generated/stellar/offer_entry/ext.rb +24 -0
  112. data/generated/stellar/offer_entry_flags.rb +21 -0
  113. data/generated/stellar/operation.rb +65 -0
  114. data/generated/stellar/operation/body.rb +88 -0
  115. data/generated/stellar/operation_meta.rb +18 -0
  116. data/generated/stellar/operation_result.rb +67 -0
  117. data/generated/stellar/operation_result/tr.rb +89 -0
  118. data/generated/stellar/operation_result_code.rb +25 -0
  119. data/generated/stellar/operation_type.rb +52 -0
  120. data/generated/stellar/participant_entry.rb +39 -0
  121. data/generated/stellar/participant_entry/ext.rb +24 -0
  122. data/generated/stellar/participant_state.rb +25 -0
  123. data/generated/stellar/path_payment_op.rb +32 -0
  124. data/generated/stellar/path_payment_result.rb +38 -0
  125. data/generated/stellar/path_payment_result/success.rb +22 -0
  126. data/generated/stellar/path_payment_result_code.rb +47 -0
  127. data/generated/stellar/payment_op.rb +22 -0
  128. data/generated/stellar/payment_result.rb +25 -0
  129. data/generated/stellar/payment_result_code.rb +41 -0
  130. data/generated/stellar/peer_address.rb +33 -0
  131. data/generated/stellar/peer_address/ip.rb +29 -0
  132. data/generated/stellar/price.rb +20 -0
  133. data/generated/stellar/proof_entry.rb +42 -0
  134. data/generated/stellar/proof_entry/ext.rb +24 -0
  135. data/generated/stellar/provide_proof_op.rb +24 -0
  136. data/generated/stellar/provide_proof_result.rb +25 -0
  137. data/generated/stellar/provide_proof_result_code.rb +22 -0
  138. data/generated/stellar/public_key.rb +23 -0
  139. data/generated/stellar/register_participant_op.rb +22 -0
  140. data/generated/stellar/register_participant_result.rb +25 -0
  141. data/generated/stellar/register_participant_result_code.rb +22 -0
  142. data/generated/stellar/scp_ballot.rb +20 -0
  143. data/generated/stellar/scp_envelope.rb +20 -0
  144. data/generated/stellar/scp_history_entry.rb +23 -0
  145. data/generated/stellar/scp_history_entry_v0.rb +20 -0
  146. data/generated/stellar/scp_nomination.rb +22 -0
  147. data/generated/stellar/scp_quorum_set.rb +22 -0
  148. data/generated/stellar/scp_statement.rb +58 -0
  149. data/generated/stellar/scp_statement/pledges.rb +63 -0
  150. data/generated/stellar/scp_statement/pledges/confirm.rb +30 -0
  151. data/generated/stellar/scp_statement/pledges/externalize.rb +26 -0
  152. data/generated/stellar/scp_statement/pledges/prepare.rb +32 -0
  153. data/generated/stellar/scp_statement_type.rb +26 -0
  154. data/generated/stellar/send_message_op.rb +22 -0
  155. data/generated/stellar/send_message_result.rb +25 -0
  156. data/generated/stellar/send_message_result_code.rb +22 -0
  157. data/generated/stellar/set_options_op.rb +41 -0
  158. data/generated/stellar/set_options_result.rb +25 -0
  159. data/generated/stellar/set_options_result_code.rb +40 -0
  160. data/generated/stellar/signer.rb +20 -0
  161. data/generated/stellar/simple_payment_result.rb +22 -0
  162. data/generated/stellar/stellar_message.rb +74 -0
  163. data/generated/stellar/stellar_value.rb +41 -0
  164. data/generated/stellar/stellar_value/ext.rb +24 -0
  165. data/generated/stellar/threshold_indexes.rb +26 -0
  166. data/generated/stellar/time_bounds.rb +20 -0
  167. data/generated/stellar/transaction.rb +50 -0
  168. data/generated/stellar/transaction/ext.rb +24 -0
  169. data/generated/stellar/transaction_envelope.rb +20 -0
  170. data/generated/stellar/transaction_history_entry.rb +33 -0
  171. data/generated/stellar/transaction_history_entry/ext.rb +24 -0
  172. data/generated/stellar/transaction_history_result_entry.rb +33 -0
  173. data/generated/stellar/transaction_history_result_entry/ext.rb +24 -0
  174. data/generated/stellar/transaction_meta.rb +23 -0
  175. data/generated/stellar/transaction_result.rb +43 -0
  176. data/generated/stellar/transaction_result/ext.rb +24 -0
  177. data/generated/stellar/transaction_result/result.rb +30 -0
  178. data/generated/stellar/transaction_result_code.rb +45 -0
  179. data/generated/stellar/transaction_result_pair.rb +20 -0
  180. data/generated/stellar/transaction_result_set.rb +18 -0
  181. data/generated/stellar/transaction_set.rb +20 -0
  182. data/generated/stellar/trust_line_entry.rb +41 -0
  183. data/generated/stellar/trust_line_entry/ext.rb +24 -0
  184. data/generated/stellar/trust_line_flags.rb +21 -0
  185. data/lib/stellar-base.rb +33 -0
  186. data/lib/stellar/account_flags.rb +28 -0
  187. data/lib/stellar/asset.rb +69 -0
  188. data/lib/stellar/base.rb +1 -0
  189. data/lib/stellar/base/version.rb +5 -0
  190. data/lib/stellar/convert.rb +32 -0
  191. data/lib/stellar/key_pair.rb +112 -0
  192. data/lib/stellar/networks.rb +45 -0
  193. data/lib/stellar/operation.rb +384 -0
  194. data/lib/stellar/path_payment_result.rb +17 -0
  195. data/lib/stellar/price.rb +32 -0
  196. data/lib/stellar/thresholds.rb +39 -0
  197. data/lib/stellar/transaction.rb +205 -0
  198. data/lib/stellar/transaction_envelope.rb +32 -0
  199. data/lib/stellar/util/continued_fraction.rb +96 -0
  200. data/lib/stellar/util/strkey.rb +43 -0
  201. data/spec/lib/stellar/account_flags_spec.rb +19 -0
  202. data/spec/lib/stellar/asset_spec.rb +45 -0
  203. data/spec/lib/stellar/convert_spec.rb +61 -0
  204. data/spec/lib/stellar/key_pair_spec.rb +238 -0
  205. data/spec/lib/stellar/networks_spec.rb +77 -0
  206. data/spec/lib/stellar/operation_spec.rb +13 -0
  207. data/spec/lib/stellar/path_payment_result_spec.rb +95 -0
  208. data/spec/lib/stellar/price_spec.rb +34 -0
  209. data/spec/lib/stellar/thresholds_spec.rb +62 -0
  210. data/spec/lib/stellar/transaction_envelope_spec.rb +93 -0
  211. data/spec/lib/stellar/transaction_spec.rb +83 -0
  212. data/spec/lib/stellar/util/strkey_spec.rb +46 -0
  213. data/spec/spec_helper.rb +16 -0
  214. data/spec/support/matchers/be_strkey.rb +9 -0
  215. data/spec/support/matchers/eq_bytes.rb +5 -0
  216. data/spec/support/matchers/have_length.rb +5 -0
  217. data/tasks/rspec.rake +6 -0
  218. data/tasks/travis.rake +1 -0
  219. data/tasks/xdr.rake +50 -0
  220. data/xdr/Stellar-SCP.x +86 -0
  221. data/xdr/Stellar-ledger-entries.x +351 -0
  222. data/xdr/Stellar-ledger.x +288 -0
  223. data/xdr/Stellar-overlay.x +146 -0
  224. data/xdr/Stellar-transaction.x +936 -0
  225. data/xdr/Stellar-types.x +55 -0
  226. metadata +495 -0
@@ -0,0 +1,39 @@
1
+ module Stellar
2
+ class << Thresholds
3
+ COMPONENTS = [:master_weight, :low, :medium, :high]
4
+ VALID_RANGE = 0..255
5
+
6
+ def make(thresholds={})
7
+
8
+ # error if any of the needed components are not provided
9
+ if COMPONENTS.any?{|c| thresholds[c].blank? }
10
+ raise ArgumentError, "invalid thresholds hash, must have #{COMPONENTS.inspect} keys, had: #{thresholds.keys.inspect}"
11
+ end
12
+
13
+ # error if any of the needed components are not numbers 0 <= N <= 255
14
+ COMPONENTS.each do |c|
15
+ good = true
16
+
17
+ good &&= thresholds[c].is_a?(Fixnum)
18
+ good &&= VALID_RANGE.include? thresholds[c]
19
+
20
+ unless good
21
+ raise ArgumentError, "invalid #{c.inspect}, must be number in (0..255), got #{thresholds[c].inspect}"
22
+ end
23
+ end
24
+
25
+
26
+ thresholds.values_at(*COMPONENTS).pack("C*")
27
+ end
28
+
29
+ def parse(combined)
30
+ master_weight, low, medium, high = combined.unpack("C*")
31
+ {
32
+ master_weight: master_weight,
33
+ low: low,
34
+ medium: medium,
35
+ high: high,
36
+ }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,205 @@
1
+ module Stellar
2
+ class Transaction
3
+
4
+ #
5
+ # @see Stellar::Operation.payment
6
+ def self.payment(attributes={})
7
+ make :payment, attributes
8
+ end
9
+
10
+ #
11
+ # @see Stellar::Operation.path_payment
12
+ def self.path_payment(attributes={})
13
+ make :path_payment, attributes
14
+ end
15
+
16
+ #
17
+ # @see Stellar::Operation.create_account
18
+ def self.create_account(attributes={})
19
+ make :create_account, attributes
20
+ end
21
+
22
+ #
23
+ # @see Stellar::Operation.create_account
24
+ def self.provide_proof(attributes={})
25
+ make :provide_proof, attributes
26
+ end
27
+
28
+ #
29
+ # @see Stellar::Operation.create_lot
30
+ def self.create_lot(attributes={})
31
+ make :create_lot, attributes
32
+ end
33
+
34
+ def self.register_participant(attributes={})
35
+ make :register_participant, attributes
36
+ end
37
+
38
+ #
39
+ # @see Stellar::Operation.change_trust
40
+ def self.change_trust(attributes={})
41
+ make :change_trust, attributes
42
+ end
43
+
44
+ #
45
+ # @see Stellar::Operation.create_offer
46
+ def self.manage_offer(attributes={})
47
+ make :manage_offer, attributes
48
+ end
49
+
50
+ #
51
+ # @see Stellar::Operation.create_passive_offer
52
+ def self.create_passive_offer(attributes={})
53
+ make :create_passive_offer, attributes
54
+ end
55
+
56
+ #
57
+ # @see Stellar::Operation.set_options
58
+ def self.set_options(attributes={})
59
+ make :set_options, attributes
60
+ end
61
+
62
+ #
63
+ # @see Stellar::Operation.allow_trust
64
+ def self.allow_trust(attributes={})
65
+ make :allow_trust, attributes
66
+ end
67
+
68
+ #
69
+ # @see Stellar::Operation.account_merge
70
+ def self.account_merge(attributes={})
71
+ make :account_merge, attributes
72
+ end
73
+
74
+ #
75
+ # @see Stellar::Operation.inflation
76
+ def self.inflation(attributes={})
77
+ make :inflation, attributes
78
+ end
79
+
80
+ #
81
+ # Helper method to create a transaction with a single
82
+ # operation of the provided type. See class methods
83
+ # on Stellar::Operation for available values for
84
+ # operation_type.
85
+ #
86
+ # @see Stellar::Operation
87
+ #
88
+ # @param operation_type [Symbol] the operation to use
89
+ # @param attributes={} [Hash] attributes to use for both the transaction and the operation
90
+ #
91
+ # @return [Stellar::Transaction] the resulting transaction
92
+ def self.make(operation_type, attributes={})
93
+ for_account(attributes).tap do |result|
94
+ result.operations << Operation.send(operation_type, attributes)
95
+ end
96
+ end
97
+
98
+
99
+ #
100
+ # Helper method to create the skeleton of a transaction.
101
+ # The resulting transaction will have its source account,
102
+ # sequence, fee, min ledger and max ledger set.
103
+ #
104
+ #
105
+ # @param attributes={} [type] [description]
106
+ #
107
+ # @return [Stellar::Transaction] the resulting skeleton
108
+ def self.for_account(attributes={})
109
+ account = attributes[:account]
110
+ sequence = attributes[:sequence]
111
+ fee = attributes[:fee]
112
+
113
+ raise ArgumentError, "Bad :account" unless account.is_a?(KeyPair)
114
+ raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
115
+ raise ArgumentError, "Bad :fee #{sequence}" if fee.present? && !fee.is_a?(Integer)
116
+
117
+ new.tap do |result|
118
+ result.seq_num = sequence
119
+ result.fee = fee
120
+ result.memo = make_memo(attributes[:memo])
121
+ result.source_account = account.account_id
122
+ result.apply_defaults
123
+ end
124
+ end
125
+
126
+ def sign(key_pair)
127
+ key_pair.sign(hash)
128
+ end
129
+
130
+ def sign_decorated(key_pair)
131
+ key_pair.sign_decorated(hash)
132
+ end
133
+
134
+ def hash
135
+ Digest::SHA256.digest(signature_base)
136
+ end
137
+
138
+ # Returns the string of bytes that, when hashed, provide the value which
139
+ # should be signed to create a valid stellar transaciton signature
140
+ def signature_base
141
+ signature_base_prefix + to_xdr
142
+ end
143
+
144
+ def signature_base_prefix
145
+ val = Stellar::EnvelopeType.envelope_type_tx
146
+
147
+ Stellar.current_network_id + Stellar::EnvelopeType.to_xdr(val)
148
+ end
149
+
150
+ def to_envelope(*key_pairs)
151
+ signatures = key_pairs.map(&method(:sign_decorated))
152
+ TransactionEnvelope.new({
153
+ :signatures => signatures,
154
+ :tx => self
155
+ })
156
+ end
157
+
158
+ def merge(other)
159
+ cloned = Marshal.load Marshal.dump(self)
160
+ cloned.operations += other.to_operations
161
+ cloned
162
+ end
163
+
164
+
165
+ #
166
+ # Extracts the operations from this single transaction,
167
+ # setting the source account on the extracted operations.
168
+ #
169
+ # Useful for merging transactions.
170
+ #
171
+ # @return [Array<Operation>] the operations
172
+ def to_operations
173
+ cloned = Marshal.load Marshal.dump(operations)
174
+ operations.each do |op|
175
+ op.source_account = self.source_account
176
+ end
177
+ end
178
+
179
+ def apply_defaults
180
+ self.operations ||= []
181
+ self.fee ||= 100
182
+ self.memo ||= Memo.new(:memo_none)
183
+ self.ext ||= Stellar::Transaction::Ext.new 0
184
+ end
185
+
186
+ private
187
+ def self.make_memo(memo)
188
+ case memo
189
+ when Stellar::Memo ;
190
+ memo
191
+ when nil ;
192
+ nil
193
+ when Integer ;
194
+ Memo.new(:memo_id, memo)
195
+ when String ;
196
+ Memo.new(:memo_text, memo)
197
+ when Array ;
198
+ t, val = *memo
199
+ Memo.new(:"memo_#{t}", val)
200
+ else
201
+ raise ArgumentError, "Bad :memo"
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,32 @@
1
+ module Stellar
2
+ class TransactionEnvelope
3
+
4
+ #
5
+ # Checks to ensure that every signature for the envelope is
6
+ # a valid signature of one of the provided `key_pairs`
7
+ #
8
+ # NOTE: this does not do any authorization checks, which requires access to
9
+ # the current ledger state.
10
+ #
11
+ # @param *key_pairs [Array<Stellar::KeyPair>] The key pairs to check the envelopes signatures against
12
+ #
13
+ # @return [Boolean] true if all signatures are from the provided key_pairs and validly sign the tx's hash
14
+ def signed_correctly?(*key_pairs)
15
+ hash = tx.hash
16
+ return false if signatures.empty?
17
+
18
+ key_index = key_pairs.index_by(&:signature_hint)
19
+
20
+ signatures.all? do |sig|
21
+ key_pair = key_index[sig.hint]
22
+ break false if key_pair.nil?
23
+
24
+ key_pair.verify(sig.signature, hash)
25
+ end
26
+ end
27
+
28
+ def hash
29
+ Digest::SHA256.digest(to_xdr)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,96 @@
1
+ module Stellar
2
+ module Util
3
+ class ContinuedFraction
4
+ MAX_PRECISION = (2**32) - 1
5
+ attr_reader :i
6
+ attr_reader :f
7
+
8
+ def self.best_r(number, max_precision=MAX_PRECISION)
9
+ cur_cf = new(number)
10
+
11
+ loop do
12
+ next_cf = cur_cf.extend()
13
+ cur_r = cur_cf.to_r(max_precision)
14
+ next_r = next_cf.to_r(max_precision)
15
+
16
+ break cur_r if cur_cf.done? || cur_r == next_r
17
+
18
+ cur_cf = next_cf
19
+ end
20
+
21
+ cur_cf.to_r(max_precision)
22
+ end
23
+
24
+ def initialize(val, parents=[])
25
+ @i = val.floor
26
+ @f = val - @i
27
+ @parents = parents
28
+ end
29
+
30
+ def to_a
31
+ @parents + [i]
32
+ end
33
+
34
+ def error(actual)
35
+ (actual - to_f).abs
36
+ end
37
+
38
+ def to_f
39
+ convergent = convergents.last
40
+ convergent.n / convergent.d.to_f
41
+ end
42
+
43
+ def convergents
44
+ return @convergents if defined? @convergents
45
+
46
+ c = [Fraction.new(0,1), Fraction.new(1,0)]
47
+ to_a.each_with_index do |a, i|
48
+ i = i + 2
49
+
50
+ h = a * c[i-1].n + c[i-2].n
51
+ k = a * c[i-1].d + c[i-2].d
52
+ c << Fraction.new(h,k)
53
+ end
54
+
55
+ @converegents = c[2..-1]
56
+ end
57
+
58
+ def to_r(max_precision=MAX_PRECISION)
59
+ fraction = convergents.take_while do |c|
60
+ c.n <= max_precision && c.d <= max_precision
61
+ end.last
62
+
63
+ Rational(fraction.n, fraction.d)
64
+ end
65
+
66
+ def done?
67
+ @f == 0
68
+ end
69
+
70
+ def extend(count=1)
71
+ result = self
72
+
73
+ count.times do
74
+ break if result.done?
75
+ result = ContinuedFraction.new(1 / result.f, result.to_a)
76
+ end
77
+
78
+ result
79
+ end
80
+
81
+ class Fraction
82
+ attr_reader :n
83
+ attr_reader :d
84
+
85
+ def initialize(n,d)
86
+ @n = n
87
+ @d = d
88
+ end
89
+
90
+ def to_r
91
+ Rational(@n, @d)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,43 @@
1
+ module Stellar
2
+ module Util
3
+
4
+ require 'base32'
5
+ require 'digest/crc16_xmodem'
6
+
7
+ class StrKey
8
+
9
+ VERSION_BYTES = {
10
+ account_id: [ 6 << 3].pack("C"), # Base32-encodes to 'G...'
11
+ seed: [18 << 3].pack("C"), # Base32-encodes to 'S...'
12
+ }
13
+
14
+ def self.check_encode(version, byte_str)
15
+ version_byte = VERSION_BYTES[version]
16
+ raise ArgumentError, "Invalid version: #{version}" if version_byte.blank?
17
+ payload = version_byte + byte_str.dup.force_encoding("BINARY")
18
+ check = checksum(payload)
19
+ Base32.encode(payload + check)
20
+ end
21
+
22
+ def self.check_decode(expected_version, str)
23
+ decoded = Base32.decode(str) rescue (raise ArgumentError, "Invalid base32 string")
24
+ version_byte = decoded[0]
25
+ payload = decoded[1...-2]
26
+ check = decoded[-2..-1]
27
+ version = VERSION_BYTES.key(version_byte)
28
+
29
+ raise ArgumentError, "Unexpected version: #{version.inspect}" if version != expected_version
30
+ raise ArgumentError, "Invalid checksum" if check != checksum(decoded[0...-2])
31
+ payload
32
+ end
33
+
34
+ # return the "XModem CRC16" (CCITT-like, but with 0-init and MSB first)
35
+ # packed into a string in little-endian order
36
+ def self.checksum(bytes)
37
+ crc = Digest::CRC16XModem.checksum(bytes)
38
+ [crc].pack("S<")
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stellar::AccountFlags do
4
+ subject{ Stellar::AccountFlags }
5
+ let(:raw) { 3 }
6
+ let(:result) { subject.parse_mask raw }
7
+
8
+ it "parses correctly" do
9
+ expect(subject.parse_mask(1)).to eq([Stellar::AccountFlags.auth_required_flag])
10
+ expect(subject.parse_mask(2)).to eq([Stellar::AccountFlags.auth_revocable_flag])
11
+ expect(subject.parse_mask(3)).to eq([Stellar::AccountFlags.auth_required_flag, Stellar::AccountFlags.auth_revocable_flag])
12
+ end
13
+
14
+ it "makes correctly" do
15
+ expect(subject.make_mask([Stellar::AccountFlags.auth_required_flag])).to eq(1)
16
+ expect(subject.make_mask([Stellar::AccountFlags.auth_revocable_flag])).to eq(2)
17
+ expect(subject.make_mask([Stellar::AccountFlags.auth_required_flag, Stellar::AccountFlags.auth_revocable_flag])).to eq(3)
18
+ end
19
+ end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe Stellar::Asset, ".native" do
4
+ it "returns a asset instance whose type is 'AssetType.asset_type_native'" do
5
+ expect(Stellar::Asset.native.type).to eq(Stellar::AssetType.asset_type_native)
6
+ end
7
+ end
8
+
9
+ describe Stellar::Asset, ".alphanum4" do
10
+ it "returns a asset instance whose type is 'AssetType.asset_type_credit_alphanum4'" do
11
+ result = Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master)
12
+ expect(result.type).to eq(Stellar::AssetType.asset_type_credit_alphanum4)
13
+ end
14
+
15
+ it "pads the code to 4 bytes, padding on the right and with null bytes" do
16
+ result = Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master)
17
+ expect(result.code).to eq("USD\x00")
18
+ end
19
+ end
20
+
21
+ describe Stellar::Asset, ".alphanum12" do
22
+ it "returns a asset instance whose type is 'AssetType.asset_type_credit_alphanum12'" do
23
+ result = Stellar::Asset.alphanum12("USD", Stellar::KeyPair.master)
24
+ expect(result.type).to eq(Stellar::AssetType.asset_type_credit_alphanum12)
25
+ end
26
+
27
+ it "pads the code to 12 bytes, padding on the right and with null bytes" do
28
+ result = Stellar::Asset.alphanum12("USD", Stellar::KeyPair.master)
29
+ expect(result.code).to eq("USD\x00\x00\x00\x00\x00\x00\x00\x00\x00")
30
+ end
31
+ end
32
+
33
+ describe Stellar::Asset, "#code" do
34
+ it "returns the asset_code for either alphanum4 or alphanum12 assets" do
35
+ a4 = Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master)
36
+ a12 = Stellar::Asset.alphanum12("USD", Stellar::KeyPair.master)
37
+
38
+ expect(a4.code.strip).to eq("USD")
39
+ expect(a12.code.strip).to eq("USD")
40
+ end
41
+
42
+ it "raises an error when called on a native asset" do
43
+ expect{ Stellar::Asset.native.code }.to raise_error(RuntimeError)
44
+ end
45
+ end