open-core 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) 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/CONTRIBUTING.md +48 -0
  6. data/Gemfile +15 -0
  7. data/Guardfile +5 -0
  8. data/LICENSE.txt +202 -0
  9. data/README.md +83 -0
  10. data/Rakefile +4 -0
  11. data/examples/create_account.rb +26 -0
  12. data/examples/low_level_transaction_post.rb +46 -0
  13. data/examples/mid_level_transaction_post.rb +33 -0
  14. data/examples/non_native_payment.rb +60 -0
  15. data/examples/offer.rb +75 -0
  16. data/examples/transaction_merge.rb +23 -0
  17. data/generated/stellar-base-generated.rb +134 -0
  18. data/generated/stellar/account_entry.rb +53 -0
  19. data/generated/stellar/account_entry/ext.rb +24 -0
  20. data/generated/stellar/account_flags.rb +27 -0
  21. data/generated/stellar/account_merge_result.rb +26 -0
  22. data/generated/stellar/account_merge_result_code.rb +30 -0
  23. data/generated/stellar/allow_trust_op.rb +38 -0
  24. data/generated/stellar/allow_trust_op/asset.rb +33 -0
  25. data/generated/stellar/allow_trust_result.rb +25 -0
  26. data/generated/stellar/allow_trust_result_code.rb +31 -0
  27. data/generated/stellar/asset.rb +47 -0
  28. data/generated/stellar/asset/alpha_num12.rb +22 -0
  29. data/generated/stellar/asset/alpha_num4.rb +22 -0
  30. data/generated/stellar/asset_type.rb +24 -0
  31. data/generated/stellar/bucket_entry.rb +28 -0
  32. data/generated/stellar/bucket_entry_type.rb +22 -0
  33. data/generated/stellar/change_trust_op.rb +22 -0
  34. data/generated/stellar/change_trust_result.rb +25 -0
  35. data/generated/stellar/change_trust_result_code.rb +30 -0
  36. data/generated/stellar/claim_offer_atom.rb +33 -0
  37. data/generated/stellar/create_account_op.rb +20 -0
  38. data/generated/stellar/create_account_result.rb +25 -0
  39. data/generated/stellar/create_account_result_code.rb +32 -0
  40. data/generated/stellar/create_passive_offer_op.rb +24 -0
  41. data/generated/stellar/crypto_key_type.rb +20 -0
  42. data/generated/stellar/decorated_signature.rb +20 -0
  43. data/generated/stellar/dont_have.rb +20 -0
  44. data/generated/stellar/envelope_type.rb +22 -0
  45. data/generated/stellar/error.rb +20 -0
  46. data/generated/stellar/hello.rb +26 -0
  47. data/generated/stellar/inflation_payout.rb +20 -0
  48. data/generated/stellar/inflation_result.rb +26 -0
  49. data/generated/stellar/inflation_result_code.rb +24 -0
  50. data/generated/stellar/ledger_entry.rb +44 -0
  51. data/generated/stellar/ledger_entry/data.rb +33 -0
  52. data/generated/stellar/ledger_entry/ext.rb +24 -0
  53. data/generated/stellar/ledger_entry_change.rb +31 -0
  54. data/generated/stellar/ledger_entry_change_type.rb +24 -0
  55. data/generated/stellar/ledger_entry_type.rb +24 -0
  56. data/generated/stellar/ledger_header.rb +65 -0
  57. data/generated/stellar/ledger_header/ext.rb +24 -0
  58. data/generated/stellar/ledger_header_history_entry.rb +33 -0
  59. data/generated/stellar/ledger_header_history_entry/ext.rb +24 -0
  60. data/generated/stellar/ledger_key.rb +50 -0
  61. data/generated/stellar/ledger_key/account.rb +20 -0
  62. data/generated/stellar/ledger_key/offer.rb +22 -0
  63. data/generated/stellar/ledger_key/trust_line.rb +22 -0
  64. data/generated/stellar/ledger_upgrade.rb +27 -0
  65. data/generated/stellar/ledger_upgrade_type.rb +22 -0
  66. data/generated/stellar/manage_offer_effect.rb +24 -0
  67. data/generated/stellar/manage_offer_op.rb +28 -0
  68. data/generated/stellar/manage_offer_result.rb +26 -0
  69. data/generated/stellar/manage_offer_result_code.rb +48 -0
  70. data/generated/stellar/manage_offer_success_result.rb +34 -0
  71. data/generated/stellar/manage_offer_success_result/offer.rb +30 -0
  72. data/generated/stellar/memo.rb +38 -0
  73. data/generated/stellar/memo_type.rb +28 -0
  74. data/generated/stellar/message_type.rb +45 -0
  75. data/generated/stellar/offer_entry.rb +49 -0
  76. data/generated/stellar/offer_entry/ext.rb +24 -0
  77. data/generated/stellar/offer_entry_flags.rb +21 -0
  78. data/generated/stellar/operation.rb +51 -0
  79. data/generated/stellar/operation/body.rb +60 -0
  80. data/generated/stellar/operation_meta.rb +18 -0
  81. data/generated/stellar/operation_result.rb +53 -0
  82. data/generated/stellar/operation_result/tr.rb +61 -0
  83. data/generated/stellar/operation_result_code.rb +25 -0
  84. data/generated/stellar/operation_type.rb +38 -0
  85. data/generated/stellar/path_payment_op.rb +32 -0
  86. data/generated/stellar/path_payment_result.rb +34 -0
  87. data/generated/stellar/path_payment_result/success.rb +22 -0
  88. data/generated/stellar/path_payment_result_code.rb +45 -0
  89. data/generated/stellar/payment_op.rb +22 -0
  90. data/generated/stellar/payment_result.rb +25 -0
  91. data/generated/stellar/payment_result_code.rb +39 -0
  92. data/generated/stellar/peer_address.rb +22 -0
  93. data/generated/stellar/price.rb +20 -0
  94. data/generated/stellar/public_key.rb +23 -0
  95. data/generated/stellar/scp_ballot.rb +20 -0
  96. data/generated/stellar/scp_envelope.rb +20 -0
  97. data/generated/stellar/scp_nomination.rb +22 -0
  98. data/generated/stellar/scp_quorum_set.rb +22 -0
  99. data/generated/stellar/scp_statement.rb +59 -0
  100. data/generated/stellar/scp_statement/pledges.rb +64 -0
  101. data/generated/stellar/scp_statement/pledges/confirm.rb +28 -0
  102. data/generated/stellar/scp_statement/pledges/externalize.rb +28 -0
  103. data/generated/stellar/scp_statement/pledges/prepare.rb +32 -0
  104. data/generated/stellar/scp_statement_type.rb +26 -0
  105. data/generated/stellar/set_options_op.rb +41 -0
  106. data/generated/stellar/set_options_result.rb +25 -0
  107. data/generated/stellar/set_options_result_code.rb +38 -0
  108. data/generated/stellar/signer.rb +20 -0
  109. data/generated/stellar/simple_payment_result.rb +22 -0
  110. data/generated/stellar/stellar_message.rb +66 -0
  111. data/generated/stellar/stellar_value.rb +40 -0
  112. data/generated/stellar/stellar_value/ext.rb +24 -0
  113. data/generated/stellar/threshold_indexes.rb +26 -0
  114. data/generated/stellar/time_bounds.rb +20 -0
  115. data/generated/stellar/transaction.rb +50 -0
  116. data/generated/stellar/transaction/ext.rb +24 -0
  117. data/generated/stellar/transaction_envelope.rb +20 -0
  118. data/generated/stellar/transaction_history_entry.rb +33 -0
  119. data/generated/stellar/transaction_history_entry/ext.rb +24 -0
  120. data/generated/stellar/transaction_history_result_entry.rb +33 -0
  121. data/generated/stellar/transaction_history_result_entry/ext.rb +24 -0
  122. data/generated/stellar/transaction_meta.rb +31 -0
  123. data/generated/stellar/transaction_meta/v0.rb +22 -0
  124. data/generated/stellar/transaction_result.rb +43 -0
  125. data/generated/stellar/transaction_result/ext.rb +24 -0
  126. data/generated/stellar/transaction_result/result.rb +30 -0
  127. data/generated/stellar/transaction_result_code.rb +45 -0
  128. data/generated/stellar/transaction_result_pair.rb +20 -0
  129. data/generated/stellar/transaction_result_set.rb +18 -0
  130. data/generated/stellar/transaction_set.rb +20 -0
  131. data/generated/stellar/trust_line_entry.rb +41 -0
  132. data/generated/stellar/trust_line_entry/ext.rb +24 -0
  133. data/generated/stellar/trust_line_flags.rb +21 -0
  134. data/lib/stellar-base.rb +32 -0
  135. data/lib/stellar/account_flags.rb +28 -0
  136. data/lib/stellar/asset.rb +69 -0
  137. data/lib/stellar/base.rb +1 -0
  138. data/lib/stellar/base/version.rb +5 -0
  139. data/lib/stellar/convert.rb +32 -0
  140. data/lib/stellar/key_pair.rb +112 -0
  141. data/lib/stellar/networks.rb +45 -0
  142. data/lib/stellar/operation.rb +304 -0
  143. data/lib/stellar/path_payment_result.rb +17 -0
  144. data/lib/stellar/price.rb +32 -0
  145. data/lib/stellar/thresholds.rb +39 -0
  146. data/lib/stellar/transaction.rb +170 -0
  147. data/lib/stellar/transaction_envelope.rb +32 -0
  148. data/lib/stellar/util/continued_fraction.rb +96 -0
  149. data/lib/stellar/util/strkey.rb +43 -0
  150. data/open-core.gemspec +37 -0
  151. data/spec/lib/stellar/account_flags_spec.rb +19 -0
  152. data/spec/lib/stellar/asset_spec.rb +45 -0
  153. data/spec/lib/stellar/convert_spec.rb +61 -0
  154. data/spec/lib/stellar/key_pair_spec.rb +238 -0
  155. data/spec/lib/stellar/networks_spec.rb +77 -0
  156. data/spec/lib/stellar/path_payment_result_spec.rb +95 -0
  157. data/spec/lib/stellar/price_spec.rb +34 -0
  158. data/spec/lib/stellar/thresholds_spec.rb +62 -0
  159. data/spec/lib/stellar/transaction_envelope_spec.rb +93 -0
  160. data/spec/lib/stellar/transaction_spec.rb +54 -0
  161. data/spec/lib/stellar/util/strkey_spec.rb +46 -0
  162. data/spec/spec_helper.rb +16 -0
  163. data/spec/support/matchers/be_strkey.rb +9 -0
  164. data/spec/support/matchers/eq_bytes.rb +5 -0
  165. data/spec/support/matchers/have_length.rb +5 -0
  166. data/tasks/rspec.rake +6 -0
  167. data/tasks/travis.rake +1 -0
  168. data/tasks/xdr.rake +50 -0
  169. data/xdr/Stellar-SCP.x +87 -0
  170. data/xdr/Stellar-ledger-entries.x +222 -0
  171. data/xdr/Stellar-ledger.x +231 -0
  172. data/xdr/Stellar-overlay.x +87 -0
  173. data/xdr/Stellar-transaction.x +670 -0
  174. data/xdr/Stellar-types.x +34 -0
  175. metadata +444 -0
@@ -0,0 +1 @@
1
+ require "stellar-base"
@@ -0,0 +1,5 @@
1
+ module Stellar
2
+ module Base
3
+ VERSION = "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ module Stellar
2
+ #
3
+ # Generic format conversion module
4
+ #
5
+ module Convert
6
+ require 'base64'
7
+
8
+ def to_hex(string)
9
+ string.unpack("H*").first
10
+ end
11
+
12
+ def from_hex(hex_string)
13
+ [hex_string].pack("H*")
14
+ end
15
+
16
+ def to_base64(string)
17
+ Base64.strict_encode64(string)
18
+ end
19
+
20
+ def from_base64(base64_string)
21
+ Base64.strict_decode64(base64_string)
22
+ end
23
+
24
+ ## Converts a Stellar::PublicKey instance (or any typedef of it such as
25
+ # Stellar::AccountID) to an address
26
+ def pk_to_address(pk)
27
+ Stellar::Util::StrKey.check_encode(:account_id, pk.ed25519!)
28
+ end
29
+
30
+ extend self
31
+ end
32
+ end
@@ -0,0 +1,112 @@
1
+ module Stellar
2
+ class KeyPair
3
+ def self.from_seed(seed)
4
+ seed_bytes = Util::StrKey.check_decode(:seed, seed)
5
+ from_raw_seed seed_bytes
6
+ end
7
+
8
+ def self.from_raw_seed(seed_bytes)
9
+ secret_key = RbNaCl::SigningKey.new(seed_bytes)
10
+ public_key = secret_key.verify_key
11
+ new(public_key, secret_key)
12
+ end
13
+
14
+ def self.from_public_key(pk_bytes)
15
+ public_key = RbNaCl::VerifyKey.new(pk_bytes)
16
+ new(public_key)
17
+ end
18
+
19
+ def self.from_address(address)
20
+ pk_bytes = Util::StrKey.check_decode(:account_id, address)
21
+ from_public_key(pk_bytes)
22
+ end
23
+
24
+ def self.random
25
+ secret_key = RbNaCl::SigningKey.generate
26
+ public_key = secret_key.verify_key
27
+ new(public_key, secret_key)
28
+ end
29
+
30
+ def self.from_network_passphrase(passphrase)
31
+ network_id = Digest::SHA256.digest(passphrase)
32
+ from_raw_seed network_id
33
+ end
34
+
35
+ def self.master
36
+ from_raw_seed(Stellar.current_network_id)
37
+ end
38
+
39
+ def initialize(public_key, secret_key=nil)
40
+ @public_key = public_key
41
+ @secret_key = secret_key
42
+ end
43
+
44
+ def account_id
45
+ Stellar::AccountID.new :key_type_ed25519, raw_public_key
46
+ end
47
+
48
+ def public_key
49
+ Stellar::PublicKey.new :key_type_ed25519, raw_public_key
50
+ end
51
+
52
+ def raw_public_key
53
+ @public_key.to_bytes
54
+ end
55
+
56
+ def signature_hint
57
+ # take last 4 bytes
58
+ account_id.to_xdr.slice(-4, 4)
59
+ end
60
+
61
+ def raw_seed
62
+ @secret_key.to_bytes
63
+ end
64
+
65
+ def rbnacl_signing_key
66
+ @secret_key
67
+ end
68
+
69
+ def rbnacl_verify_key
70
+ @public_key
71
+ end
72
+
73
+ def address
74
+ pk_bytes = raw_public_key
75
+ Util::StrKey.check_encode(:account_id, pk_bytes)
76
+ end
77
+
78
+ def seed
79
+ raise "no private key" if @secret_key.nil?
80
+ #TODO: improve the error class above
81
+ seed_bytes = raw_seed
82
+ encoder = Util::StrKey.check_encode(:seed, seed_bytes)
83
+ end
84
+
85
+ def sign?
86
+ !@secret_key.nil?
87
+ end
88
+
89
+ def sign(message)
90
+ raise "no private key" if @secret_key.nil?
91
+ #TODO: improve the error class above
92
+ @secret_key.sign(message)
93
+ end
94
+
95
+ def sign_decorated(message)
96
+ raw_signature = sign(message)
97
+ Stellar::DecoratedSignature.new({
98
+ hint: signature_hint,
99
+ signature: raw_signature
100
+ })
101
+ end
102
+
103
+ def verify(signature, message)
104
+ @public_key.verify(signature, message)
105
+ rescue RbNaCl::LengthError
106
+ false
107
+ rescue RbNaCl::BadSignatureError
108
+ false
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,45 @@
1
+ module Stellar
2
+ # Provides a container for well-known network passphrases, such as the main network and SDF test network
3
+ module Networks
4
+
5
+ PUBLIC = "Public Global Stellar Network ; September 2015"
6
+ TESTNET = "Test SDF Network ; September 2015"
7
+
8
+ end
9
+
10
+ # Configures the default stellar network passphrase for the current process. Unless otherwise
11
+ # specified in a method that needs the passphrase, this value will be used.
12
+ #
13
+ # NOTE: This method is not thread-safe. It's best to just call this at startup once and use the other
14
+ # methods of specifying a network if you need two threads in the same process to communicate with
15
+ # different networks
16
+ #
17
+ # @see Stellar.default_network
18
+ # @see Stellar.on_network
19
+ def self.default_network=(passphrase)
20
+ @default_network = passphrase
21
+ end
22
+
23
+ # Returns the passphrase for the currently-configured network, as set by Stellar.default_network
24
+ # or Stellar.on_network
25
+ def self.current_network
26
+ Thread.current["stellar_network_passphrase"] ||
27
+ @default_network ||
28
+ Stellar::Networks::PUBLIC
29
+ end
30
+
31
+ # Returns the id for the currently configured network, suitable for use in generating
32
+ # a signature base string or making the root account's keypair.
33
+ def self.current_network_id
34
+ Digest::SHA256.digest(self.current_network)
35
+ end
36
+
37
+ # Executes the provided block in the context of the provided network.
38
+ def self.on_network(passphrase, &block)
39
+ old = Thread.current["stellar_network_passphrase"]
40
+ Thread.current["stellar_network_passphrase"] = passphrase
41
+ block.call
42
+ ensure
43
+ Thread.current["stellar_network_passphrase"] = old
44
+ end
45
+ end
@@ -0,0 +1,304 @@
1
+ require 'bigdecimal'
2
+
3
+ module Stellar
4
+ class Operation
5
+
6
+
7
+ #
8
+ # Construct a new Stellar::Operation from the provided
9
+ # source account and body
10
+ #
11
+ # @param [Hash] attributes the attributes to create the operation with
12
+ # @option attributes [Stellar::KeyPair] :source_account
13
+ # @option attributes [Stellar::Operation::Body] :body
14
+ #
15
+ # @return [Stellar::Operation] the built operation
16
+ def self.make(attributes={})
17
+ source_account = attributes[:source_account]
18
+ body = Stellar::Operation::Body.new(*attributes[:body])
19
+
20
+ op = Stellar::Operation.new(body:body)
21
+
22
+ if source_account
23
+ raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
24
+ op.source_account = source_account.account_id
25
+ end
26
+
27
+ return op
28
+ end
29
+
30
+
31
+ #
32
+ # Helper method to create a valid PaymentOp, wrapped
33
+ # in the necessary XDR structs to be included within a
34
+ # transactions `operations` array.
35
+ #
36
+ # @see Stellar::Asset
37
+ #
38
+ # @param [Hash] attributes the attributes to create the operation with
39
+ # @option attributes [Stellar::KeyPair] :destination the receiver of the payment
40
+ # @option attributes [Array] :amount the amount to pay
41
+ # @return [Stellar::Operation] the built operation, containing a
42
+ # Stellar::PaymentOp body
43
+ def self.payment(attributes={})
44
+ destination = attributes[:destination]
45
+ asset, amount = extract_amount(attributes[:amount])
46
+
47
+ raise ArgumentError unless destination.is_a?(KeyPair)
48
+
49
+
50
+ op = PaymentOp.new
51
+ op.asset = asset
52
+ op.amount = amount
53
+ op.destination = destination.account_id
54
+
55
+ return make(attributes.merge({
56
+ body:[:payment, op]
57
+ }))
58
+ end
59
+
60
+ #
61
+ # Helper method to create a valid PathPaymentOp, wrapped
62
+ # in the necessary XDR structs to be included within a
63
+ # transactions `operations` array.
64
+ #
65
+ # @see Stellar::Asset
66
+ #
67
+ # @param [Hash] attributes the attributes to create the operation with
68
+ # @option attributes [Stellar::KeyPair] :destination the receiver of the payment
69
+ # @option attributes [Array] :amount the amount to pay
70
+ # @option attributes [Array] :with the source asset and maximum allowed source amount to pay with
71
+ # @option attributes [Array<Stellar::Asset>] :path the payment path to use
72
+ #
73
+ # @return [Stellar::Operation] the built operation, containing a
74
+ # Stellar::PaymentOp body
75
+ def self.path_payment(attributes={})
76
+ destination = attributes[:destination]
77
+ asset, amount = extract_amount(attributes[:amount])
78
+ send_asset, send_max = extract_amount(attributes[:with])
79
+ path = (attributes[:path] || []).map{|p| Stellar::Asset.send(*p)}
80
+
81
+ raise ArgumentError unless destination.is_a?(KeyPair)
82
+
83
+ op = PathPaymentOp.new
84
+ op.send_asset = send_asset
85
+ op.send_max = send_max
86
+ op.destination = destination.account_id
87
+ op.dest_asset = asset
88
+ op.dest_amount = amount
89
+ op.path = path
90
+
91
+ return make(attributes.merge({
92
+ body:[:path_payment, op]
93
+ }))
94
+ end
95
+
96
+ def self.create_account(attributes={})
97
+ destination = attributes[:destination]
98
+ starting_balance = attributes[:starting_balance]
99
+
100
+ raise ArgumentError unless destination.is_a?(KeyPair)
101
+
102
+ op = CreateAccountOp.new()
103
+ op.destination = destination.account_id
104
+ op.starting_balance = starting_balance
105
+
106
+ return make(attributes.merge({
107
+ body:[:create_account, op]
108
+ }))
109
+ end
110
+
111
+ #
112
+ # Helper method to create a valid ChangeTrustOp, wrapped
113
+ # in the necessary XDR structs to be included within a
114
+ # transactions `operations` array.
115
+ #
116
+ # @param [Hash] attributes the attributes to create the operation with
117
+ # @option attributes [Stellar::Currrency] :line the asset to trust
118
+ # @option attributes [Fixnum] :limit the maximum amount to trust
119
+ #
120
+ # @return [Stellar::Operation] the built operation, containing a
121
+ # Stellar::ChangeTrustOp body
122
+ def self.change_trust(attributes={})
123
+ line = Asset.send(*attributes[:line])
124
+ limit = attributes[:limit]
125
+
126
+ raise ArgumentError, "Bad :limit #{limit}" unless limit.is_a?(Integer)
127
+
128
+ op = ChangeTrustOp.new(line: line, limit: limit)
129
+
130
+ return make(attributes.merge({
131
+ body:[:change_trust, op]
132
+ }))
133
+ end
134
+
135
+ def self.manage_offer(attributes={})
136
+ buying = Asset.send(*attributes[:buying])
137
+ selling = Asset.send(*attributes[:selling])
138
+ amount = attributes[:amount]
139
+ offer_id = attributes[:offer_id] || 0
140
+ price = interpret_price(attributes[:price])
141
+
142
+ op = ManageOfferOp.new({
143
+ buying: buying,
144
+ selling: selling,
145
+ amount: amount,
146
+ price: price,
147
+ offer_id: offer_id
148
+ })
149
+
150
+ return make(attributes.merge({
151
+ body:[:manage_offer, op]
152
+ }))
153
+ end
154
+
155
+ def self.create_passive_offer(attributes={})
156
+ buying = Asset.send(*attributes[:buying])
157
+ selling = Asset.send(*attributes[:selling])
158
+ amount = attributes[:amount]
159
+ price = interpret_price(attributes[:price])
160
+
161
+ op = CreatePassiveOfferOp.new({
162
+ buying: buying,
163
+ selling: selling,
164
+ amount: amount,
165
+ price: price,
166
+ })
167
+
168
+ return make(attributes.merge({
169
+ body:[:create_passive_offer, op]
170
+ }))
171
+ end
172
+
173
+ #
174
+ # Helper method to create a valid SetOptionsOp, wrapped
175
+ # in the necessary XDR structs to be included within a
176
+ # transactions `operations` array.
177
+ #
178
+ # @param [Hash] attributes the attributes to create the operation with
179
+ # @option attributes [Stellar::KeyPair] :inflation_dest
180
+ # @option attributes [Array<Stellar::AccountFlags>] :set flags to set
181
+ # @option attributes [Array<Stellar::AccountFlags>] :clear flags to clear
182
+ # @option attributes [String] :thresholds
183
+ # @option attributes [Stellar::Signer] :signer
184
+ #
185
+ # @return [Stellar::Operation] the built operation, containing a
186
+ # Stellar::SetOptionsOp body
187
+ def self.set_options(attributes={})
188
+ op = SetOptionsOp.new()
189
+ op.set_flags = Stellar::AccountFlags.make_mask attributes[:set]
190
+ op.clear_flags = Stellar::AccountFlags.make_mask attributes[:clear]
191
+ op.master_weight = attributes[:master_weight]
192
+ op.low_threshold = attributes[:low_threshold]
193
+ op.med_threshold = attributes[:med_threshold]
194
+ op.high_threshold = attributes[:high_threshold]
195
+
196
+ op.signer = attributes[:signer]
197
+ op.home_domain = attributes[:home_domain]
198
+
199
+
200
+ inflation_dest = attributes[:inflation_dest]
201
+ if inflation_dest
202
+ raise ArgumentError, "Bad :inflation_dest" unless inflation_dest.is_a?(Stellar::KeyPair)
203
+ op.inflation_dest = inflation_dest.account_id
204
+ end
205
+
206
+
207
+ return make(attributes.merge({
208
+ body:[:set_options, op]
209
+ }))
210
+ end
211
+
212
+ #
213
+ # Helper method to create a valid AllowTrustOp, wrapped
214
+ # in the necessary XDR structs to be included within a
215
+ # transactions `operations` array.
216
+ #
217
+ # @param [Hash] attributes the attributes to create the operation with
218
+ # @option attributes [Stellar::KeyPair] :trustor
219
+ # @option attributes [Stellar::Asset] :asset
220
+ #
221
+ # @return [Stellar::Operation] the built operation, containing a
222
+ # Stellar::AllowTrustOp body
223
+ def self.allow_trust(attributes={})
224
+ op = AllowTrustOp.new()
225
+
226
+ trustor = attributes[:trustor]
227
+ authorize = attributes[:authorize]
228
+ asset = Asset.send(*attributes[:asset])
229
+
230
+ raise ArgumentError, "Bad :trustor" unless trustor.is_a?(Stellar::KeyPair)
231
+ raise ArgumentError, "Bad :authorize" unless authorize == !!authorize # check boolean
232
+ raise ArgumentError, "Bad :asset" unless asset.type == Stellar::AssetType.asset_type_credit_alphanum4
233
+
234
+ atc = AllowTrustOp::Asset.new(:asset_type_credit_alphanum4, asset.code)
235
+
236
+ op.trustor = trustor.account_id
237
+ op.authorize = authorize
238
+ op.asset = atc
239
+
240
+ return make(attributes.merge({
241
+ body:[:allow_trust, op]
242
+ }))
243
+ end
244
+
245
+ #
246
+ # Helper method to create an account merge operation
247
+ #
248
+ # @param [Hash] attributes the attributes to create the operation with
249
+ # @option attributes [Stellar::KeyPair] :destination
250
+ #
251
+ # @return [Stellar::Operation] the built operation
252
+ def self.account_merge(attributes={})
253
+ destination = attributes[:destination]
254
+
255
+ raise ArgumentError, "Bad :destination" unless destination.is_a?(KeyPair)
256
+
257
+ # TODO: add source_account support
258
+ return make(attributes.merge({
259
+ body:[:account_merge, destination.account_id]
260
+ }))
261
+ end
262
+
263
+ #
264
+ # Helper method to create an inflation operation
265
+ #
266
+ # @param [Hash] attributes the attributes to create the operation with
267
+ # @option attributes [Integer] :sequence
268
+ #
269
+ # @return [Stellar::Operation] the built operation
270
+ def self.inflation(attributes={})
271
+ sequence = attributes[:sequence]
272
+
273
+ raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
274
+
275
+ # TODO: add source_account support
276
+ return make(attributes.merge({
277
+ body:[:inflation]
278
+ }))
279
+ end
280
+
281
+ private
282
+ def self.extract_amount(a)
283
+ amount = a.last
284
+ asset = Stellar::Asset.send(*a[0...-1])
285
+
286
+ return asset, amount
287
+ end
288
+
289
+
290
+ def self.interpret_price(price)
291
+ case price
292
+ when String
293
+ bd = BigDecimal.new(price)
294
+ Price.from_f(bd)
295
+ when Numeric
296
+ Price.from_f(price)
297
+ when Stellar::Price
298
+ price
299
+ else
300
+ raise ArgumentError, "Invalid price type: #{price.class}. Must be String, Numeric, or Stellar::Price"
301
+ end
302
+ end
303
+ end
304
+ end