open-core 0.3.0

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 (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