stellar-base 0.23.0.rc2 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +111 -1
  3. data/README.md +4 -7
  4. data/generated/stellar-base-generated.rb +29 -1
  5. data/generated/stellar/account_entry.rb +3 -13
  6. data/generated/stellar/account_entry/ext.rb +2 -16
  7. data/generated/stellar/account_entry_extension_v1.rb +32 -0
  8. data/generated/stellar/account_entry_extension_v1/ext.rb +28 -0
  9. data/generated/stellar/account_entry_extension_v2.rb +34 -0
  10. data/generated/stellar/{account_entry/ext/v1 → account_entry_extension_v2}/ext.rb +8 -12
  11. data/generated/stellar/account_merge_result_code.rb +3 -1
  12. data/generated/stellar/begin_sponsoring_future_reserves_op.rb +18 -0
  13. data/generated/stellar/begin_sponsoring_future_reserves_result.rb +25 -0
  14. data/generated/stellar/begin_sponsoring_future_reserves_result_code.rb +29 -0
  15. data/generated/stellar/claim_claimable_balance_op.rb +18 -0
  16. data/generated/stellar/claim_claimable_balance_result.rb +25 -0
  17. data/generated/stellar/claim_claimable_balance_result_code.rb +31 -0
  18. data/generated/stellar/claim_predicate.rb +43 -0
  19. data/generated/stellar/claim_predicate_type.rb +30 -0
  20. data/generated/stellar/claimable_balance_entry.rb +44 -0
  21. data/generated/stellar/claimable_balance_entry/ext.rb +24 -0
  22. data/generated/stellar/claimable_balance_id.rb +23 -0
  23. data/generated/stellar/claimable_balance_id_type.rb +20 -0
  24. data/generated/stellar/claimant.rb +31 -0
  25. data/generated/stellar/claimant/v0.rb +22 -0
  26. data/generated/stellar/claimant_type.rb +20 -0
  27. data/generated/stellar/create_claimable_balance_op.rb +22 -0
  28. data/generated/stellar/create_claimable_balance_result.rb +27 -0
  29. data/generated/stellar/create_claimable_balance_result_code.rb +30 -0
  30. data/generated/stellar/end_sponsoring_future_reserves_result.rb +25 -0
  31. data/generated/stellar/end_sponsoring_future_reserves_result_code.rb +25 -0
  32. data/generated/stellar/envelope_type.rb +3 -1
  33. data/generated/stellar/inner_transaction_result.rb +2 -1
  34. data/generated/stellar/inner_transaction_result/result.rb +3 -1
  35. data/generated/stellar/ledger_entry.rb +4 -0
  36. data/generated/stellar/ledger_entry/data.rb +12 -8
  37. data/generated/stellar/ledger_entry/ext.rb +4 -0
  38. data/generated/stellar/ledger_entry_extension_v1.rb +30 -0
  39. data/generated/stellar/ledger_entry_extension_v1/ext.rb +24 -0
  40. data/generated/stellar/ledger_entry_type.rb +7 -5
  41. data/generated/stellar/ledger_key.rb +17 -8
  42. data/generated/stellar/ledger_key/claimable_balance.rb +20 -0
  43. data/generated/stellar/operation.rb +10 -0
  44. data/generated/stellar/operation/body.rb +45 -26
  45. data/generated/stellar/operation_id.rb +32 -0
  46. data/generated/stellar/operation_id/id.rb +24 -0
  47. data/generated/stellar/operation_result.rb +10 -0
  48. data/generated/stellar/operation_result/tr.rb +48 -28
  49. data/generated/stellar/operation_result_code.rb +3 -1
  50. data/generated/stellar/operation_type.rb +25 -15
  51. data/generated/stellar/path_payment_strict_receive_result.rb +2 -1
  52. data/generated/stellar/revoke_sponsorship_op.rb +36 -0
  53. data/generated/stellar/revoke_sponsorship_op/signer.rb +22 -0
  54. data/generated/stellar/revoke_sponsorship_result.rb +25 -0
  55. data/generated/stellar/revoke_sponsorship_result_code.rb +31 -0
  56. data/generated/stellar/revoke_sponsorship_type.rb +22 -0
  57. data/generated/stellar/transaction_result_code.rb +4 -2
  58. data/lib/stellar-base.rb +18 -5
  59. data/lib/stellar/account_flags.rb +1 -1
  60. data/lib/stellar/asset.rb +10 -0
  61. data/lib/stellar/{version.rb → base/version.rb} +1 -1
  62. data/lib/stellar/claim_predicate.rb +198 -0
  63. data/lib/stellar/compat.rb +2 -15
  64. data/lib/stellar/concerns/transaction.rb +2 -3
  65. data/lib/stellar/dsl.rb +89 -0
  66. data/lib/stellar/ext/xdr.rb +50 -0
  67. data/lib/stellar/key_pair.rb +60 -53
  68. data/lib/stellar/ledger_key.rb +32 -0
  69. data/lib/stellar/muxed_account.rb +16 -0
  70. data/lib/stellar/networks.rb +12 -12
  71. data/lib/stellar/operation.rb +59 -1
  72. data/lib/stellar/price.rb +11 -2
  73. data/lib/stellar/transaction.rb +17 -167
  74. data/lib/stellar/transaction_builder.rb +35 -18
  75. data/lib/stellar/transaction_envelope.rb +7 -43
  76. data/lib/stellar/transaction_v0.rb +5 -1
  77. data/lib/stellar/util/strkey.rb +6 -6
  78. metadata +164 -32
  79. data/generated/stellar/account_entry/ext/v1.rb +0 -34
  80. data/lib/stellar/util/continued_fraction.rb +0 -96
@@ -0,0 +1,32 @@
1
+ require "stellar/convert"
2
+ require "stellar/dsl"
3
+
4
+ module Stellar
5
+ class LedgerKey
6
+ class << self
7
+ include Stellar::DSL
8
+
9
+ def switch_for_arm(name)
10
+ (@switch_by_arm ||= switches.invert).fetch(name)
11
+ end
12
+
13
+ def from(account_id:, **options)
14
+ field, value = options.first
15
+ case field
16
+ when nil
17
+ account(account_id: KeyPair(account_id).account_id)
18
+ when :balance_id
19
+ claimable_balance(balance_id: ClaimableBalanceID.v0(Stellar::Convert.from_hex(value.to_s)))
20
+ when :offer_id
21
+ offer(seller_id: account_id, offer_id: Integer(value))
22
+ when :data_name
23
+ data(account_id: account_id, data_name: value.to_s)
24
+ when :asset
25
+ trust_line(account_id: account_id, asset: Asset(value))
26
+ else
27
+ raise ArgumentError, "unknown option #{field} (not in :asset, :offer_id, :data_name, :balance_id)"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,16 @@
1
+ module Stellar
2
+ class MuxedAccount
3
+ def to_keypair
4
+ case arm
5
+ when :ed25519 then KeyPair.from_public_key(value)
6
+ when :med25519 then KeyPair.from_public_key(value.ed25519)
7
+ else
8
+ raise "impossible"
9
+ end
10
+ end
11
+
12
+ def address
13
+ to_keypair.address
14
+ end
15
+ end
16
+ end
@@ -12,18 +12,18 @@ module Stellar
12
12
  # methods of specifying a network if you need two threads in the same process to communicate with
13
13
  # different networks
14
14
  #
15
- # @see Stellar.default_network
16
15
  # @see Stellar.on_network
17
- def self.default_network=(passphrase)
18
- @default_network = passphrase
19
- end
16
+ mattr_accessor :default_network, default: Networks::TESTNET
17
+
18
+ # Stellar network passphrase selected for current thread
19
+ #
20
+ # @see Stellar.current_network
21
+ # @see Stellar.on_network
22
+ thread_mattr_accessor :network
20
23
 
21
- # Returns the passphrase for the currently-configured network, as set by Stellar.default_network
22
- # or Stellar.on_network
24
+ # Returns the passphrase for the network currently active per-thread with a fallback to `Stellar.default_network`
23
25
  def self.current_network
24
- Thread.current["stellar_network_passphrase"] ||
25
- @default_network ||
26
- Stellar::Networks::TESTNET
26
+ network.presence || default_network
27
27
  end
28
28
 
29
29
  # Returns the id for the currently configured network, suitable for use in generating
@@ -34,10 +34,10 @@ module Stellar
34
34
 
35
35
  # Executes the provided block in the context of the provided network.
36
36
  def self.on_network(passphrase, &block)
37
- old = Thread.current["stellar_network_passphrase"]
38
- Thread.current["stellar_network_passphrase"] = passphrase
37
+ old = network
38
+ self.network = passphrase
39
39
  block.call
40
40
  ensure
41
- Thread.current["stellar_network_passphrase"] = old
41
+ self.network = old
42
42
  end
43
43
  end
@@ -5,6 +5,7 @@ module Stellar
5
5
  MAX_INT64 = 2**63 - 1
6
6
 
7
7
  class << self
8
+ include Stellar::DSL
8
9
  #
9
10
  # Construct a new Stellar::Operation from the provided
10
11
  # source account and body
@@ -168,7 +169,6 @@ module Stellar
168
169
  }))
169
170
  end
170
171
 
171
- #
172
172
  # Helper method to create a valid ChangeTrustOp, wrapped
173
173
  # in the necessary XDR structs to be included within a
174
174
  # transactions `operations` array.
@@ -200,6 +200,64 @@ module Stellar
200
200
  }))
201
201
  end
202
202
 
203
+ # Helper method to create a valid CreateClaimableBalanceOp, ready to be used
204
+ # within a transactions `operations` array.
205
+ #
206
+ # @see Stellar::DSL::Claimant
207
+ # @see https://github.com/astroband/ruby-stellar-sdk/tree/master/base/examples/claimable_balances.rb
208
+ #
209
+ # @param asset [Asset] the asset to transfer to a claimable balance
210
+ # @param amount [Fixnum] the amount of `asset` to put into a claimable balance
211
+ # @param claimants [Array<Claimant>] accounts authorized to claim the balance in the future
212
+ #
213
+ # @return [Operation] the built operation
214
+ def create_claimable_balance(asset:, amount:, claimants:, **attributes)
215
+ op = CreateClaimableBalanceOp.new(asset: asset, amount: amount, claimants: claimants)
216
+
217
+ make(attributes.merge(body: [:create_claimable_balance, op]))
218
+ end
219
+
220
+ # Helper method to create a valid CreateClaimableBalanceOp, ready to be used
221
+ # within a transactions `operations` array.
222
+ #
223
+ # @see Stellar::DSL::Claimant
224
+ # @see https://github.com/astroband/ruby-stellar-sdk/tree/master/base/examples/claimable_balances.rb
225
+ #
226
+ # @param balance_id [ClaimableBalanceID] unique ID of claimable balance
227
+ #
228
+ # @return [Operation] the built operation, containing a Stellar::ChangeTrustOp body
229
+ def claim_claimable_balance(balance_id:, **attributes)
230
+ op = ClaimClaimableBalanceOp.new(balance_id: balance_id)
231
+
232
+ make(attributes.merge(body: [:claim_claimable_balance, op]))
233
+ end
234
+
235
+ def begin_sponsoring_future_reserves(sponsored:, **attributes)
236
+ op = BeginSponsoringFutureReservesOp.new(
237
+ sponsored_id: KeyPair(sponsored).account_id
238
+ )
239
+
240
+ make(attributes.merge(body: [:begin_sponsoring_future_reserves, op]))
241
+ end
242
+
243
+ def end_sponsoring_future_reserves(**attributes)
244
+ make(attributes.merge(body: [:end_sponsoring_future_reserves]))
245
+ end
246
+
247
+ # @param sponsored [#to_keypair] owner of sponsored entry
248
+ def revoke_sponsorship(sponsored:, **attributes)
249
+ key_fields = attributes.slice(:offer_id, :data_name, :balance_id, :asset, :signer)
250
+ raise ArgumentError, "conflicting attributes: #{key_fields.keys.join(", ")}" if key_fields.size > 1
251
+ account_id = KeyPair(sponsored).account_id
252
+ key, value = key_fields.first
253
+ op = if key == :signer
254
+ RevokeSponsorshipOp.signer(account_id: account_id, signer_key: SignerKey(value))
255
+ else
256
+ RevokeSponsorshipOp.ledger_key(LedgerKey.from(account_id: account_id, **key_fields))
257
+ end
258
+ make(attributes.merge(body: [:revoke_sponsorship, op]))
259
+ end
260
+
203
261
  def manage_sell_offer(attributes = {})
204
262
  buying = attributes[:buying]
205
263
  if buying.is_a?(Array)
@@ -4,7 +4,12 @@ module Stellar
4
4
  MAX_PRECISION = (2**31) - 1
5
5
 
6
6
  def self.from_f(number)
7
- best_r = Util::ContinuedFraction.best_r(number, MAX_PRECISION)
7
+ best_r = number.to_r.rationalize(1.0e-7)
8
+
9
+ if best_r.numerator > MAX_PRECISION || best_r.denominator > MAX_PRECISION
10
+ raise ArgumentError("Couldn't find price approximation")
11
+ end
12
+
8
13
  new({
9
14
  n: best_r.numerator,
10
15
  d: best_r.denominator
@@ -15,8 +20,12 @@ module Stellar
15
20
  self.class.new(n: d, d: n)
16
21
  end
17
22
 
23
+ def to_d
24
+ n.to_d / d
25
+ end
26
+
18
27
  def to_f
19
- n / d.to_f
28
+ n.to_f / d
20
29
  end
21
30
 
22
31
  def to_s
@@ -2,172 +2,22 @@ module Stellar
2
2
  class Transaction
3
3
  include Stellar::Concerns::Transaction
4
4
 
5
- class << self
6
- #
7
- # @see Stellar::Operation.payment
8
- def payment(attributes = {})
9
- make :payment, attributes
10
- end
11
-
12
- #
13
- # @see Stellar::Operation.path_payment
14
- def path_payment(attributes = {})
15
- make :path_payment, attributes
16
- end
17
-
18
- #
19
- # @see Stellar::Operation.path_payment_strict_receive
20
- def path_payment_strict_receive(attributes = {})
21
- make :path_payment_strict_receive, attributes
22
- end
23
-
24
- #
25
- # @see Stellar::Operation.path_payment_strict_send
26
- def path_payment_strict_send(attributes = {})
27
- make :path_payment_strict_send, attributes
28
- end
29
-
30
- #
31
- # @see Stellar::Operation.create_account
32
- def create_account(attributes = {})
33
- make :create_account, attributes
34
- end
35
-
36
- #
37
- # @see Stellar::Operation.change_trust
38
- def change_trust(attributes = {})
39
- make :change_trust, attributes
40
- end
41
-
42
- #
43
- # @see Stellar::Operation.manage_sell_offer
44
- def manage_sell_offer(attributes = {})
45
- make :manage_sell_offer, attributes
46
- end
47
-
48
- #
49
- # @see Stellar::Operation.manage_buy_offer
50
- def manage_buy_offer(attributes = {})
51
- make :manage_buy_offer, attributes
52
- end
53
-
54
- #
55
- # @see Stellar::Operation.create_passive_sell_offer
56
- def create_passive_sell_offer(attributes = {})
57
- make :create_passive_sell_offer, attributes
58
- end
59
-
60
- #
61
- # @see Stellar::Operation.set_options
62
- def set_options(attributes = {})
63
- make :set_options, attributes
64
- end
65
-
66
- #
67
- # @see Stellar::Operation.allow_trust
68
- def allow_trust(attributes = {})
69
- make :allow_trust, attributes
70
- end
71
-
72
- #
73
- # @see Stellar::Operation.account_merge
74
- def account_merge(attributes = {})
75
- make :account_merge, attributes
76
- end
77
-
78
- #
79
- # @see Stellar::Operation.inflation
80
- def inflation(attributes = {})
81
- make :inflation, attributes
82
- end
83
-
84
- #
85
- # @see Stellar::Operation.manage_data
86
- def manage_data(attributes = {})
87
- make :manage_data, attributes
88
- end
89
-
90
- #
91
- # @see Stellar::Operation.manage_data
92
- def bump_sequence(attributes = {})
93
- make :bump_sequence, attributes
94
- end
95
-
96
- #
97
- # DEPRECATED
98
- #
99
- # All methods calling make() have been deprecated in favor of Stellar::TransactionBuilder.
100
- # These functions only create single-operation transactions and essentially duplicate the
101
- # methods provided by Stellar::Operation. Stellar::TransactionBuilder enables the construction
102
- # of multi-operation transactions and mirrors the functionality provided by the Python and
103
- # JavaScript SDKs.
104
- #
105
- # Helper method to create a transaction with a single
106
- # operation of the provided type. See class methods
107
- # on Stellar::Operation for available values for
108
- # operation_type.
109
- #
110
- # @see Stellar::Operation
111
- #
112
- # @param operation_type [Symbol] the operation to use
113
- # @param attributes={} [Hash] attributes to use for both the transaction and the operation
114
- #
115
- # @return [Stellar::Transaction] the resulting transaction
116
- def make(operation_type, attributes = {})
117
- Stellar::Deprecation.warn(
118
- "Transaction.#{operation_type} is deprecated. Use Stellar::TransactionBuilder instead."
119
- )
120
- for_account(attributes).tap do |result|
121
- result.operations << Operation.send(operation_type, attributes)
122
- end
123
- end
124
-
125
- #
126
- # Helper method to create the skeleton of a transaction.
127
- # The resulting transaction will have its source account,
128
- # sequence, fee, min ledger and max ledger set.
129
- #
130
- #
131
- # @param attributes={} [type] [description]
132
- #
133
- # @return [Stellar::Transaction] the resulting skeleton
134
- def for_account(attributes = {})
135
- account = attributes[:account]
136
- sequence = attributes[:sequence]
137
- fee = attributes[:fee]
138
-
139
- raise ArgumentError, "Bad :account" unless account.is_a?(KeyPair)
140
- raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
141
- raise ArgumentError, "Bad :fee #{sequence}" if fee.present? && !fee.is_a?(Integer)
142
-
143
- new.tap do |result|
144
- result.seq_num = sequence
145
- result.fee = fee
146
- result.memo = make_memo(attributes[:memo])
147
- result.source_account = account.muxed_account
148
- result.apply_defaults
149
- end
150
- end
151
-
152
- private
153
-
154
- def make_memo(memo)
155
- case memo
156
- when Stellar::Memo
157
- memo
158
- when nil
159
- nil
160
- when Integer
161
- Memo.new(:memo_id, memo)
162
- when String
163
- Memo.new(:memo_text, memo)
164
- when Array
165
- t, val = *memo
166
- Memo.new(:"memo_#{t}", val)
167
- else
168
- raise ArgumentError, "Bad :memo"
169
- end
170
- end
5
+ def to_v0
6
+ ed25519 = if source_account.switch == Stellar::CryptoKeyType.key_type_ed25519
7
+ source_account.ed25519!
8
+ else
9
+ source_account.med25519!.ed25519
10
+ end
11
+
12
+ TransactionV0.new(
13
+ source_account_ed25519: ed25519,
14
+ seq_num: seq_num,
15
+ operations: operations,
16
+ fee: fee,
17
+ memo: memo,
18
+ time_bounds: time_bounds,
19
+ ext: ext
20
+ )
171
21
  end
172
22
 
173
23
  def signature_base
@@ -179,7 +29,7 @@ module Stellar
179
29
  end
180
30
 
181
31
  def to_envelope(*key_pairs)
182
- signatures = (key_pairs || []).map(&method(:sign_decorated))
32
+ signatures = key_pairs.map(&method(:sign_decorated))
183
33
 
184
34
  TransactionEnvelope.v1(signatures: signatures, tx: self)
185
35
  end
@@ -2,13 +2,34 @@ module Stellar
2
2
  class TransactionBuilder
3
3
  attr_reader :source_account, :sequence_number, :base_fee, :time_bounds, :memo, :operations
4
4
 
5
+ class << self
6
+ # This enable user to call shortcut methods, like
7
+ # TransactionBuilder.payment(...),
8
+ # TransactionBuilder.manage_data(...) and etc.
9
+ # It reduces the boilerplate, when you just need to
10
+ # shoot a single operation in transaction
11
+ def method_missing(method_name, *args, **kwargs)
12
+ unless Stellar::Operation.respond_to?(method_name)
13
+ return super
14
+ end
15
+
16
+ op = Stellar::Operation.send(method_name, **kwargs)
17
+
18
+ new(**kwargs).add_operation(op).build
19
+ end
20
+
21
+ def respond_to_missing?(method_name, include_private = false)
22
+ Stellar::Operation.respond_to?(method_name) || super
23
+ end
24
+ end
25
+
5
26
  def initialize(
6
27
  source_account:,
7
28
  sequence_number:,
8
29
  base_fee: 100,
9
30
  time_bounds: nil,
10
31
  memo: nil,
11
- v1: false
32
+ **_ # ignore any additional parameters without errors
12
33
  )
13
34
  raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
14
35
  raise ArgumentError, "Bad :sequence_number" unless sequence_number.is_a?(Integer) && sequence_number >= 0
@@ -19,9 +40,13 @@ module Stellar
19
40
  @sequence_number = sequence_number
20
41
  @base_fee = base_fee
21
42
  @time_bounds = time_bounds
43
+
44
+ if time_bounds.nil?
45
+ set_timeout(0)
46
+ end
47
+
22
48
  @memo = make_memo(memo)
23
49
  @operations = []
24
- @v1 = v1
25
50
  end
26
51
 
27
52
  def build
@@ -34,6 +59,7 @@ module Stellar
34
59
  end
35
60
 
36
61
  attrs = {
62
+ source_account: @source_account.muxed_account,
37
63
  fee: @base_fee * @operations.length,
38
64
  seq_num: @sequence_number,
39
65
  time_bounds: @time_bounds,
@@ -42,21 +68,16 @@ module Stellar
42
68
  ext: Stellar::Transaction::Ext.new(0)
43
69
  }
44
70
 
45
- tx = if @v1
46
- attrs[:source_account] = @source_account.muxed_account
47
- Stellar::Transaction.new(attrs)
48
- else
49
- attrs[:source_account_ed25519] = @source_account.raw_public_key
50
- Stellar::TransactionV0.new(attrs)
51
- end
52
-
53
71
  @sequence_number += 1
54
- tx
72
+
73
+ Stellar::Transaction.new(attrs)
55
74
  end
56
75
 
57
76
  def build_fee_bump(inner_txe:)
58
- if inner_txe.switch != Stellar::EnvelopeType.envelope_type_tx
59
- raise "Invalid inner transaction type, it should be a `envelope_type_tx` but received a #{inner_tx.to_envelope.switch}."
77
+ if inner_txe.switch == Stellar::EnvelopeType.envelope_type_tx_v0
78
+ inner_txe = Stellar::TransactionEnvelope.v1(tx: inner_txe.tx.to_v1, signatures: inner_txe.signatures)
79
+ elsif inner_txe.switch != Stellar::EnvelopeType.envelope_type_tx
80
+ raise ArgumentError, "Invalid inner transaction type #{inner_txe.switch}"
60
81
  end
61
82
 
62
83
  inner_tx = inner_txe.tx
@@ -108,11 +129,7 @@ module Stellar
108
129
  @time_bounds = Stellar::TimeBounds.new(min_time: 0, max_time: nil)
109
130
  end
110
131
 
111
- @time_bounds.max_time = if timeout == 0
112
- timeout
113
- else
114
- Time.now.to_i + timeout
115
- end
132
+ @time_bounds.max_time = timeout == 0 ? timeout : Time.now.to_i + timeout
116
133
 
117
134
  self
118
135
  end