stellar-base 0.26.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -32
  3. data/README.md +3 -3
  4. data/generated/stellar/account_flags.rb +9 -4
  5. data/generated/stellar/account_merge_result.rb +1 -1
  6. data/generated/stellar/allow_trust_op.rb +3 -18
  7. data/generated/stellar/allow_trust_result_code.rb +4 -1
  8. data/generated/stellar/alpha_num12.rb +20 -0
  9. data/generated/stellar/alpha_num4.rb +20 -0
  10. data/generated/stellar/asset.rb +2 -15
  11. data/generated/stellar/asset_code.rb +30 -0
  12. data/generated/stellar/asset_type.rb +3 -1
  13. data/generated/stellar/begin_sponsoring_future_reserves_result.rb +2 -1
  14. data/generated/stellar/change_trust_asset.rb +39 -0
  15. data/generated/stellar/change_trust_op.rb +2 -2
  16. data/generated/stellar/change_trust_result_code.rb +13 -7
  17. data/generated/stellar/claim_atom.rb +31 -0
  18. data/generated/stellar/claim_atom_type.rb +24 -0
  19. data/generated/stellar/claim_liquidity_atom.rb +30 -0
  20. data/generated/stellar/claim_offer_atom_v0.rb +33 -0
  21. data/generated/stellar/claimable_balance_entry/ext.rb +4 -0
  22. data/generated/stellar/claimable_balance_entry.rb +2 -0
  23. data/generated/stellar/{asset/alpha_num12.rb → claimable_balance_entry_extension_v1/ext.rb} +9 -7
  24. data/generated/stellar/{operation_id.rb → claimable_balance_entry_extension_v1.rb} +12 -14
  25. data/generated/stellar/claimable_balance_flags.rb +22 -0
  26. data/generated/stellar/clawback_claimable_balance_op.rb +18 -0
  27. data/generated/stellar/clawback_claimable_balance_result.rb +26 -0
  28. data/generated/stellar/clawback_claimable_balance_result_code.rb +29 -0
  29. data/generated/stellar/clawback_op.rb +22 -0
  30. data/generated/stellar/clawback_result.rb +25 -0
  31. data/generated/stellar/clawback_result_code.rb +31 -0
  32. data/generated/stellar/create_passive_sell_offer_op.rb +1 -1
  33. data/generated/stellar/end_sponsoring_future_reserves_result.rb +2 -1
  34. data/generated/stellar/envelope_type.rb +10 -8
  35. data/generated/stellar/{operation_id/id.rb → hash_id_preimage/operation_id.rb} +4 -4
  36. data/generated/stellar/hash_id_preimage/revoke_id.rb +28 -0
  37. data/generated/stellar/hash_id_preimage.rb +44 -0
  38. data/generated/stellar/ledger_entry/data.rb +4 -0
  39. data/generated/stellar/ledger_entry.rb +2 -0
  40. data/generated/stellar/ledger_entry_type.rb +3 -1
  41. data/generated/stellar/ledger_header/ext.rb +4 -0
  42. data/generated/stellar/ledger_header.rb +2 -0
  43. data/generated/stellar/ledger_header_extension_v1/ext.rb +24 -0
  44. data/generated/stellar/ledger_header_extension_v1.rb +30 -0
  45. data/generated/stellar/ledger_header_flags.rb +24 -0
  46. data/generated/stellar/{asset/alpha_num4.rb → ledger_key/liquidity_pool.rb} +4 -6
  47. data/generated/stellar/ledger_key/trust_line.rb +2 -2
  48. data/generated/stellar/ledger_key.rb +10 -1
  49. data/generated/stellar/ledger_upgrade.rb +4 -0
  50. data/generated/stellar/ledger_upgrade_type.rb +3 -1
  51. data/generated/stellar/liquidity_pool_constant_product_parameters.rb +22 -0
  52. data/generated/stellar/liquidity_pool_deposit_op.rb +26 -0
  53. data/generated/stellar/liquidity_pool_deposit_result.rb +26 -0
  54. data/generated/stellar/liquidity_pool_deposit_result_code.rb +41 -0
  55. data/generated/stellar/liquidity_pool_entry/body/constant_product.rb +31 -0
  56. data/generated/stellar/liquidity_pool_entry/body.rb +37 -0
  57. data/generated/stellar/liquidity_pool_entry.rb +38 -0
  58. data/generated/stellar/liquidity_pool_parameters.rb +23 -0
  59. data/generated/stellar/liquidity_pool_type.rb +20 -0
  60. data/generated/stellar/liquidity_pool_withdraw_op.rb +24 -0
  61. data/generated/stellar/liquidity_pool_withdraw_result.rb +26 -0
  62. data/generated/stellar/liquidity_pool_withdraw_result_code.rb +36 -0
  63. data/generated/stellar/manage_offer_success_result.rb +2 -2
  64. data/generated/stellar/operation/body.rb +20 -0
  65. data/generated/stellar/operation.rb +10 -0
  66. data/generated/stellar/operation_result/tr.rb +20 -0
  67. data/generated/stellar/operation_result.rb +10 -0
  68. data/generated/stellar/operation_type.rb +11 -1
  69. data/generated/stellar/path_payment_strict_receive_result/success.rb +2 -2
  70. data/generated/stellar/path_payment_strict_receive_result.rb +1 -1
  71. data/generated/stellar/path_payment_strict_send_result/success.rb +2 -2
  72. data/generated/stellar/path_payment_strict_send_result.rb +1 -1
  73. data/generated/stellar/payment_result_code.rb +1 -1
  74. data/generated/stellar/revoke_sponsorship_op.rb +1 -2
  75. data/generated/stellar/revoke_sponsorship_result_code.rb +3 -1
  76. data/generated/stellar/scp_quorum_set.rb +2 -2
  77. data/generated/stellar/set_options_result_code.rb +14 -11
  78. data/generated/stellar/set_trust_line_flags_op.rb +25 -0
  79. data/generated/stellar/set_trust_line_flags_result.rb +25 -0
  80. data/generated/stellar/set_trust_line_flags_result_code.rb +34 -0
  81. data/generated/stellar/transaction_result_code.rb +1 -1
  82. data/generated/stellar/trust_line_asset.rb +39 -0
  83. data/generated/stellar/trust_line_entry/ext/v1/ext.rb +4 -0
  84. data/generated/stellar/trust_line_entry/ext/v1.rb +2 -0
  85. data/generated/stellar/trust_line_entry/ext.rb +2 -0
  86. data/generated/stellar/trust_line_entry.rb +7 -5
  87. data/generated/stellar/trust_line_entry_extension_v2/ext.rb +24 -0
  88. data/generated/stellar/trust_line_entry_extension_v2.rb +30 -0
  89. data/generated/stellar/trust_line_flags.rb +5 -1
  90. data/generated/stellar-base-generated.rb +40 -1
  91. data/lib/stellar/account.rb +59 -0
  92. data/lib/stellar/account_flags.rb +1 -1
  93. data/lib/stellar/amount.rb +36 -0
  94. data/lib/stellar/asset.rb +8 -0
  95. data/lib/stellar/compat.rb +6 -3
  96. data/lib/stellar/concerns/transaction.rb +4 -2
  97. data/lib/stellar/dsl.rb +26 -0
  98. data/lib/stellar/ledger_key.rb +5 -3
  99. data/lib/stellar/liquidity_pool/base_pool.rb +47 -0
  100. data/lib/stellar/liquidity_pool/constant_product_pool.rb +15 -0
  101. data/lib/stellar/liquidity_pool.rb +12 -0
  102. data/lib/stellar/operation.rb +357 -386
  103. data/lib/stellar/price.rb +13 -7
  104. data/lib/stellar/transaction_builder.rb +27 -11
  105. data/lib/stellar/trust_line_flags.rb +53 -0
  106. data/lib/stellar/util/strkey.rb +15 -7
  107. data/lib/stellar/version.rb +3 -0
  108. data/lib/stellar-base.rb +5 -2
  109. metadata +61 -16
  110. data/generated/stellar/allow_trust_op/asset.rb +0 -33
  111. data/lib/stellar/base/version.rb +0 -5
@@ -3,6 +3,11 @@ require "bigdecimal"
3
3
  module Stellar
4
4
  class Operation
5
5
  MAX_INT64 = 2**63 - 1
6
+ TRUST_LINE_FLAGS_MAPPING = {
7
+ full: Stellar::TrustLineFlags.authorized_flag,
8
+ maintain_liabilities: Stellar::TrustLineFlags.authorized_to_maintain_liabilities_flag,
9
+ clawback_enabled: Stellar::TrustLineFlags.trustline_clawback_enabled_flag
10
+ }.freeze
6
11
 
7
12
  class << self
8
13
  include Stellar::DSL
@@ -10,211 +15,194 @@ module Stellar
10
15
  # Construct a new Stellar::Operation from the provided
11
16
  # source account and body
12
17
  #
13
- # @param [Hash] attributes the attributes to create the operation with
14
- # @option attributes [Stellar::KeyPair] :source_account
15
- # @option attributes [Stellar::Operation::Body] :body
18
+ # @param source_account [KeyPair, nil] the source account for the operation
19
+ # @param [(Symbol, XDR::Struct)] body a tuple containing operation type and operation object
16
20
  #
17
21
  # @return [Stellar::Operation] the built operation
18
- def make(attributes = {})
19
- source_account = attributes[:source_account]
20
- body = Stellar::Operation::Body.new(*attributes[:body])
22
+ def make(body:, source_account: nil)
23
+ raise ArgumentError, "Bad :source_account" if source_account && !source_account.is_a?(Stellar::KeyPair)
21
24
 
22
- op = Stellar::Operation.new(body: body)
25
+ body = Stellar::Operation::Body.new(*body)
23
26
 
24
- if source_account
25
- raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
26
- op.source_account = source_account.muxed_account
27
- end
28
-
29
- op
27
+ Stellar::Operation.new(
28
+ source_account: source_account&.muxed_account,
29
+ body: body
30
+ )
30
31
  end
31
32
 
33
+ # Create Account operation builder
32
34
  #
33
- # Helper method to create a valid PaymentOp, wrapped
34
- # in the necessary XDR structs to be included within a
35
- # transactions `operations` array.
35
+ # @param source_account [KeyPair, nil] the source account for the operation
36
+ # @param destination [KeyPair] the account to create
37
+ # @param starting_balance [String, Numeric] the amount to deposit to the newly created account
36
38
  #
37
- # @see Stellar::Asset
38
- #
39
- # @param [Hash] attributes the attributes to create the operation with
40
- # @option attributes [Stellar::KeyPair] :destination the receiver of the payment
41
- # @option attributes [Array] :amount the amount to pay
42
- # @return [Stellar::Operation] the built operation, containing a
43
- # Stellar::PaymentOp body
44
- def payment(attributes = {})
45
- destination = attributes[:destination]
46
- asset, amount = get_asset_amount(attributes[:amount])
47
-
48
- raise ArgumentError unless destination.is_a?(KeyPair)
49
-
50
- op = PaymentOp.new
51
- op.asset = asset
52
- op.amount = amount
53
- op.destination = destination.muxed_account
39
+ # @return [Stellar::Operation] the built operation
40
+ def create_account(destination:, starting_balance:, source_account: nil)
41
+ op = CreateAccountOp.new(
42
+ destination: KeyPair(destination).account_id,
43
+ starting_balance: interpret_amount(starting_balance)
44
+ )
54
45
 
55
- make(attributes.merge({
56
- body: [:payment, op]
57
- }))
46
+ make(source_account: source_account, body: [:create_account, op])
58
47
  end
59
48
 
49
+ # Account Merge operation builder
60
50
  #
61
- # Helper method to create a valid PathPaymentStrictReceiveOp, wrapped
62
- # in the necessary XDR structs to be included within a
63
- # transactions `operations` array.
64
- #
65
- # @deprecated Please use Operation.path_payment_strict_receive
66
- #
67
- # @see Stellar::Asset
51
+ # @param [Stellar::KeyPair, nil] source_account the source account for the operation
52
+ # @param [Stellar::KeyPair] destination the account to merge into
68
53
  #
69
- # @param [Hash] attributes the attributes to create the operation with
70
- # @option attributes [Stellar::KeyPair] :destination the receiver of the payment
71
- # @option attributes [Array] :amount the destination asset and the amount to pay
72
- # @option attributes [Array] :with the source asset and maximum allowed source amount to pay with
73
- # @option attributes [Array<Stellar::Asset>] :path the payment path to use
74
- #
75
- # @return [Stellar::Operation] the built operation, containing a Stellar::PaymentOp body
76
- #
77
- def path_payment(attributes = {})
78
- path_payment_strict_receive(attributes)
54
+ # @return [Stellar::Operation] the built operation
55
+ def account_merge(destination:, source_account: nil)
56
+ raise ArgumentError, "Bad destination" unless destination.is_a?(KeyPair)
57
+
58
+ make(source_account: source_account, body: [:account_merge, destination.muxed_account])
79
59
  end
80
60
 
61
+ # Set Options operation builder.
81
62
  #
82
- # Helper method to create a valid PathPaymentStrictReceiveOp, wrapped
83
- # in the necessary XDR structs to be included within a
84
- # transactions `operations` array.
85
- #
86
- # @see Stellar::Asset
63
+ # @param source_account [KeyPair, nil] the source account for the operation
64
+ # @param home_domain [String, nil\] the home domain of the account
65
+ # @param signer [Signer, nil] add, remove or adjust weight of the co-signer
66
+ # @param set [Array<AccountFlags>] flags to set
67
+ # @param clear [Array<AccountFlags>] flags to clear
68
+ # @param inflation_dest [KeyPair, nil] the inflation destination of the account
87
69
  #
88
- # @param [Hash] attributes the attributes to create the operation with
89
- # @option attributes [Stellar::KeyPair] :destination the receiver of the payment
90
- # @option attributes [Array] :amount the destination asset and the amount to pay
91
- # @option attributes [Array] :with the source asset and maximum allowed source amount to pay with
92
- # @option attributes [Array<Stellar::Asset>] :path the payment path to use
70
+ # @return [Stellar::Operation] the built operation
71
+ def set_options(set: [], clear: [], home_domain: nil, signer: nil, inflation_dest: nil, source_account: nil, **attributes)
72
+ raise ArgumentError, "Bad inflation_dest" if inflation_dest && !inflation_dest.is_a?(KeyPair)
73
+
74
+ op = SetOptionsOp.new(
75
+ set_flags: Stellar::AccountFlags.make_mask(set),
76
+ clear_flags: Stellar::AccountFlags.make_mask(clear),
77
+ master_weight: attributes[:master_weight],
78
+ low_threshold: attributes[:low_threshold],
79
+ med_threshold: attributes[:med_threshold],
80
+ high_threshold: attributes[:high_threshold],
81
+ signer: signer,
82
+ home_domain: home_domain,
83
+ inflation_dest: inflation_dest&.account_id
84
+ )
85
+
86
+ make(source_account: source_account, body: [:set_options, op])
87
+ end
88
+
89
+ # Bump Sequence operation builder
93
90
  #
94
- # @return [Stellar::Operation] the built operation, containing a Stellar::PaymentOp body
91
+ # @param [Stellar::KeyPair] source_account the source account for the operation
92
+ # @param [Integer] bump_to the target sequence number for the account
95
93
  #
96
- def path_payment_strict_receive(attributes = {})
97
- destination = attributes[:destination]
98
- asset, amount = get_asset_amount(attributes[:amount])
99
- send_asset, send_max = get_asset_amount(attributes[:with])
100
- path = (attributes[:path] || []).map { |p|
101
- p.is_a?(Array) ? Stellar::Asset.send(*p) : p
102
- }
94
+ # @return [Stellar::Operation] the built operation
95
+ def bump_sequence(bump_to:, source_account: nil)
96
+ raise ArgumentError, ":bump_to too big" unless bump_to <= MAX_INT64
103
97
 
104
- raise ArgumentError unless destination.is_a?(KeyPair)
98
+ op = BumpSequenceOp.new(
99
+ bump_to: bump_to
100
+ )
105
101
 
106
- op = PathPaymentStrictReceiveOp.new
107
- op.send_asset = send_asset
108
- op.send_max = send_max
109
- op.destination = destination.muxed_account
110
- op.dest_asset = asset
111
- op.dest_amount = amount
112
- op.path = path
113
-
114
- make(attributes.merge({
115
- body: [:path_payment_strict_receive, op]
116
- }))
102
+ make(source_account: source_account, body: [:bump_sequence, op])
117
103
  end
118
104
 
105
+ # Manage Data operation builder
119
106
  #
120
- # Helper method to create a valid PathPaymentStrictSendOp, wrapped
121
- # in the necessary XDR structs to be included within a
122
- # transactions `operations` array.
123
- #
124
- # @see Stellar::Asset
125
- #
126
- # @param [Hash] attributes the attributes to create the operation with
127
- # @option attributes [Stellar::KeyPair] :destination the receiver of the payment
128
- # @option attributes [Array] :amount the destination asset and the minimum amount of destination asset to be received
129
- # @option attributes [Array] :with the source asset and amount to pay with
130
- # @option attributes [Array<Stellar::Asset>] :path the payment path to use
131
- #
132
- # @return [Stellar::Operation] the built operation, containing a Stellar::PaymentOp body
107
+ # @param [Stellar::KeyPair, nil] source_account the source account for the operation
108
+ # @param [String] name the name of the data entry
109
+ # @param [String, nil] value the value of the data entry (nil to remove the entry)
133
110
  #
134
- def path_payment_strict_send(attributes = {})
135
- destination = attributes[:destination]
136
- asset, dest_min = get_asset_amount(attributes[:amount])
137
- send_asset, send_amount = get_asset_amount(attributes[:with])
138
- path = (attributes[:path] || []).map { |p|
139
- p.is_a?(Array) ? Stellar::Asset.send(*p) : p
140
- }
111
+ # @return [Stellar::Operation] the built operation
112
+ def manage_data(name:, value: nil, source_account: nil)
113
+ raise ArgumentError, "Invalid :name" unless name.is_a?(String)
114
+ raise ArgumentError, ":name too long" if name.bytesize > 64
115
+ raise ArgumentError, ":value too long" if value && value.bytesize > 64
141
116
 
142
- raise ArgumentError unless destination.is_a?(KeyPair)
117
+ op = ManageDataOp.new(
118
+ data_name: name,
119
+ data_value: value
120
+ )
143
121
 
144
- op = PathPaymentStrictSendOp.new
145
- op.send_asset = send_asset
146
- op.send_amount = send_amount
147
- op.destination = destination.muxed_account
148
- op.dest_asset = asset
149
- op.dest_min = dest_min
150
- op.path = path
151
-
152
- make(attributes.merge({
153
- body: [:path_payment_strict_send, op]
154
- }))
122
+ make(source_account: source_account, body: [:manage_data, op])
155
123
  end
156
124
 
157
- def create_account(attributes = {})
158
- destination = attributes[:destination]
159
- starting_balance = interpret_amount(attributes[:starting_balance])
125
+ # Change Trust operation builder
126
+ #
127
+ # @param source_account [KeyPair, nil] the source account for the operation
128
+ # @param asset [Asset] the asset to trust
129
+ # @param limit [String, Numeric] the maximum amount to trust, defaults to max int64 (0 deletes the trustline)
130
+ #
131
+ # @return [Stellar::Operation] the built operation
132
+ def change_trust(asset: nil, limit: nil, source_account: nil, **attrs)
133
+ if attrs.key?(:line) && !asset
134
+ Stellar::Deprecation.warn("`line` parameter is deprecated, use `asset` instead")
135
+ asset = attrs[:line]
136
+ end
137
+
138
+ op = ChangeTrustOp.new(
139
+ line: Asset(asset).to_change_trust_asset,
140
+ limit: limit ? interpret_amount(limit) : MAX_INT64
141
+ )
160
142
 
161
- raise ArgumentError unless destination.is_a?(KeyPair)
143
+ make(source_account: source_account, body: [:change_trust, op])
144
+ end
162
145
 
163
- op = CreateAccountOp.new
164
- op.destination = destination.account_id
165
- op.starting_balance = starting_balance
146
+ # Set Trustline Flags operation builder
147
+ #
148
+ # @param source_account [KeyPair, nil] the source account for the operation
149
+ # @param asset [Stellar::Asset]
150
+ # @param trustor [Stellar::KeyPair]
151
+ # @param flags [{String, Symbol, Stellar::TrustLineFlags => true, false}] flags to to set or clear
152
+ #
153
+ # @return [Stellar::Operation] the built operation
154
+ def set_trust_line_flags(asset:, trustor:, flags: {}, source_account: nil)
155
+ op = Stellar::SetTrustLineFlagsOp.new(
156
+ trustor: KeyPair(trustor).account_id,
157
+ asset: Asset(asset),
158
+ attributes: TrustLineFlags.set_clear_masks(flags)
159
+ )
166
160
 
167
- make(attributes.merge({
168
- body: [:create_account, op]
169
- }))
161
+ make(source_account: source_account, body: [:set_trust_line_flags, op])
170
162
  end
171
163
 
172
- # Helper method to create a valid ChangeTrustOp, wrapped
173
- # in the necessary XDR structs to be included within a
174
- # transactions `operations` array.
175
- #
176
- # @param [Hash] attributes the attributes to create the operation with
177
- # @option attributes [Stellar::Asset] :line the asset to trust
178
- # @option attributes [Fixnum] :limit the maximum amount to trust, defaults to max int64,
179
- # if the limit is set to 0 it deletes the trustline.
180
- #
181
- # @return [Stellar::Operation] the built operation, containing a
182
- # Stellar::ChangeTrustOp body
183
- def change_trust(attributes = {})
184
- line = attributes[:line]
185
- unless line.is_a?(Asset)
186
- unless Asset::TYPES.include?(line[0])
187
- fail ArgumentError, "must be one of #{Asset::TYPES}"
188
- end
189
- line = Asset.send(*line)
190
- end
164
+ # Clawback operation builder
165
+ #
166
+ # @param [Stellar::KeyPair] source_account the source account for the operation
167
+ # @param [String|Account|PublicKey|SignerKey|KeyPair] from the account to clawback from
168
+ # @param [(Asset, Numeric)] amount the amount of asset to subtract from the balance
169
+ #
170
+ # @return [Stellar::Operation] the built operation
171
+ def clawback(from:, amount:, source_account: nil)
172
+ asset, amount = get_asset_amount(amount)
191
173
 
192
- limit = attributes.key?(:limit) ? interpret_amount(attributes[:limit]) : MAX_INT64
174
+ if amount == 0
175
+ raise ArgumentError, "Amount can not be zero"
176
+ end
193
177
 
194
- raise ArgumentError, "Bad :limit #{limit}" unless limit.is_a?(Integer)
178
+ if amount < 0
179
+ raise ArgumentError, "Negative amount is not allowed"
180
+ end
195
181
 
196
- op = ChangeTrustOp.new(line: line, limit: limit)
182
+ op = ClawbackOp.new(
183
+ amount: amount,
184
+ from: KeyPair(from).muxed_account,
185
+ asset: asset
186
+ )
197
187
 
198
- make(attributes.merge({
199
- body: [:change_trust, op]
200
- }))
188
+ make(source_account: source_account, body: [:clawback, op])
201
189
  end
202
190
 
203
- # Helper method to create a valid CreateClaimableBalanceOp, ready to be used
204
- # within a transactions `operations` array.
191
+ # Create Claimable Balance operation builder.
205
192
  #
206
193
  # @see Stellar::DSL::Claimant
207
194
  # @see https://github.com/astroband/ruby-stellar-sdk/tree/master/base/examples/claimable_balances.rb
208
195
  #
196
+ # @param source_account [KeyPair, nil] the source account for the operation
209
197
  # @param asset [Asset] the asset to transfer to a claimable balance
210
198
  # @param amount [Fixnum] the amount of `asset` to put into a claimable balance
211
199
  # @param claimants [Array<Claimant>] accounts authorized to claim the balance in the future
212
200
  #
213
201
  # @return [Operation] the built operation
214
- def create_claimable_balance(asset:, amount:, claimants:, **attributes)
202
+ def create_claimable_balance(asset:, amount:, claimants:, source_account: nil)
215
203
  op = CreateClaimableBalanceOp.new(asset: asset, amount: amount, claimants: claimants)
216
204
 
217
- make(attributes.merge(body: [:create_claimable_balance, op]))
205
+ make(source_account: source_account, body: [:create_claimable_balance, op])
218
206
  end
219
207
 
220
208
  # Helper method to create a valid CreateClaimableBalanceOp, ready to be used
@@ -223,274 +211,276 @@ module Stellar
223
211
  # @see Stellar::DSL::Claimant
224
212
  # @see https://github.com/astroband/ruby-stellar-sdk/tree/master/base/examples/claimable_balances.rb
225
213
  #
214
+ # @param source_account [KeyPair, nil] the source account for the operation
226
215
  # @param balance_id [ClaimableBalanceID] unique ID of claimable balance
227
216
  #
228
- # @return [Operation] the built operation, containing a Stellar::ChangeTrustOp body
229
- def claim_claimable_balance(balance_id:, **attributes)
217
+ # @return [Operation] the built operation
218
+ def claim_claimable_balance(balance_id:, source_account: nil)
230
219
  op = ClaimClaimableBalanceOp.new(balance_id: balance_id)
231
220
 
232
- make(attributes.merge(body: [:claim_claimable_balance, op]))
221
+ make(source_account: source_account, body: [:claim_claimable_balance, op])
233
222
  end
234
223
 
235
- def begin_sponsoring_future_reserves(sponsored:, **attributes)
236
- op = BeginSponsoringFutureReservesOp.new(
237
- sponsored_id: KeyPair(sponsored).account_id
224
+ # Clawback Claimable Balance operation builder
225
+ #
226
+ # @param [Stellar::KeyPair] source_account the source account for the operation
227
+ # @param [String] balance_id claimable balance ID as a hexadecimal string
228
+ #
229
+ # @return [Stellar::Operation] the built operation
230
+ def clawback_claimable_balance(balance_id:, source_account: nil)
231
+ balance_id = Stellar::ClaimableBalanceID.from_xdr(balance_id, :hex)
232
+ op = ClawbackClaimableBalanceOp.new(balance_id: balance_id)
233
+
234
+ make(source_account: source_account, body: [:clawback_claimable_balance, op])
235
+ rescue XDR::ReadError
236
+ raise ArgumentError, "Claimable balance id '#{balance_id}' is invalid"
237
+ end
238
+
239
+ # Payment Operation builder
240
+ #
241
+ # @param source_account [KeyPair, nil] the source account for the operation
242
+ # @param [Stellar::KeyPair] destination the receiver of the payment
243
+ # @param [(Asset, Numeric)] amount the amount to pay
244
+ #
245
+ # @return [Stellar::Operation] the built operation
246
+ def payment(destination:, amount:, source_account: nil)
247
+ raise ArgumentError unless destination.is_a?(KeyPair)
248
+ asset, amount = get_asset_amount(amount)
249
+
250
+ op = PaymentOp.new(
251
+ asset: asset,
252
+ amount: amount,
253
+ destination: destination.muxed_account
238
254
  )
239
255
 
240
- make(attributes.merge(body: [:begin_sponsoring_future_reserves, op]))
256
+ make(
257
+ source_account: source_account,
258
+ body: [:payment, op]
259
+ )
241
260
  end
242
261
 
243
- def end_sponsoring_future_reserves(**attributes)
244
- make(attributes.merge(body: [:end_sponsoring_future_reserves]))
262
+ # Path Payment Strict Receive operation builder.
263
+ #
264
+ # @param source_account [KeyPair, nil] the source account for the operation
265
+ # @param destination [Stellar::KeyPair] the receiver of the payment
266
+ # @param amount [Array] the destination asset and the amount to pay
267
+ # @param with [Array] the source asset and maximum allowed source amount to pay with
268
+ # @param path [Array<Stellar::Asset>] the payment path to use
269
+ #
270
+ # @return [Stellar::Operation] the built operation
271
+ def path_payment_strict_receive(destination:, amount:, with:, path: [], source_account: nil)
272
+ raise ArgumentError unless destination.is_a?(KeyPair)
273
+
274
+ dest_asset, dest_amount = get_asset_amount(amount)
275
+ send_asset, send_max = get_asset_amount(with)
276
+
277
+ op = PathPaymentStrictReceiveOp.new(
278
+ destination: destination.muxed_account,
279
+ dest_asset: dest_asset,
280
+ dest_amount: dest_amount,
281
+ send_asset: send_asset,
282
+ send_max: send_max,
283
+ path: path.map { |p| Asset(p) }
284
+ )
285
+
286
+ make(source_account: source_account, body: [:path_payment_strict_receive, op])
245
287
  end
288
+ alias_method :path_payment, :path_payment_strict_receive
246
289
 
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]))
290
+ # Path Payment Strict Receive operation builder.
291
+ #
292
+ # @param source_account [KeyPair, nil] the source account for the operation
293
+ # @param destination [Stellar::KeyPair] the receiver of the payment
294
+ # @param amount [Array] the destination asset and the minimum amount of destination asset to be received
295
+ # @param with [Array] the source asset and amount to pay with
296
+ # @param path [Array<Stellar::Asset>] the payment path to use
297
+ #
298
+ # @return [Stellar::Operation] the built operation
299
+ def path_payment_strict_send(destination:, amount:, with:, path: [], source_account: nil)
300
+ raise ArgumentError unless destination.is_a?(KeyPair)
301
+
302
+ dest_asset, dest_min = get_asset_amount(amount)
303
+ send_asset, send_amount = get_asset_amount(with)
304
+
305
+ op = PathPaymentStrictSendOp.new(
306
+ destination: destination.muxed_account,
307
+ send_asset: send_asset,
308
+ send_amount: send_amount,
309
+ dest_asset: dest_asset,
310
+ dest_min: dest_min,
311
+ path: path.map { |p| Asset(p) }
312
+ )
313
+
314
+ make(source_account: source_account, body: [:path_payment_strict_send, op])
259
315
  end
260
316
 
261
- def manage_sell_offer(attributes = {})
262
- buying = attributes[:buying]
263
- if buying.is_a?(Array)
264
- buying = Asset.send(*buying)
265
- end
266
- selling = attributes[:selling]
267
- if selling.is_a?(Array)
268
- selling = Asset.send(*selling)
269
- end
270
- amount = interpret_amount(attributes[:amount])
271
- offer_id = attributes[:offer_id] || 0
272
- price = interpret_price(attributes[:price])
317
+ # Manage Sell Offer operation builder
318
+ #
319
+ # @param source_account [KeyPair, nil] the source account for the operation
320
+ # @param selling [Asset] the asset to sell
321
+ # @param buying [Asset] the asset to buy
322
+ # @param amount [String, Numeric] the amount of asset to sell
323
+ # @param price [String, Numeric, Price] the price of the selling asset in terms of buying asset
324
+ # @param offer_id [Integer] the offer ID to modify (0 to create a new offer)
325
+ #
326
+ # @return [Operation] the built operation
327
+ def manage_sell_offer(selling:, buying:, amount:, price:, offer_id: 0, source_account: nil)
328
+ selling = Asset.send(*selling) if selling.is_a?(Array)
329
+ buying = Asset.send(*buying) if buying.is_a?(Array)
273
330
 
274
- op = ManageSellOfferOp.new({
331
+ op = ManageSellOfferOp.new(
275
332
  buying: buying,
276
333
  selling: selling,
277
- amount: amount,
278
- price: price,
334
+ amount: interpret_amount(amount),
335
+ price: Price.from(price),
279
336
  offer_id: offer_id
280
- })
337
+ )
281
338
 
282
- make(attributes.merge({
283
- body: [:manage_sell_offer, op]
284
- }))
339
+ make(source_account: source_account, body: [:manage_sell_offer, op])
285
340
  end
286
341
 
287
- def manage_buy_offer(attributes = {})
288
- buying = attributes[:buying]
289
- if buying.is_a?(Array)
290
- buying = Asset.send(*buying)
291
- end
292
- selling = attributes[:selling]
293
- if selling.is_a?(Array)
294
- selling = Asset.send(*selling)
295
- end
296
- amount = interpret_amount(attributes[:amount])
297
- offer_id = attributes[:offer_id] || 0
298
- price = interpret_price(attributes[:price])
342
+ # Manage Buy Offer operation builder
343
+ #
344
+ # @param source_account [KeyPair, nil] the source account for the operation
345
+ # @param buying [Asset] the asset to buy
346
+ # @param selling [Asset] the asset to sell
347
+ # @param amount [String, Numeric] the amount of asset to buy
348
+ # @param price [String, Numeric, Price] the price of the buying asset in terms of the selling asset
349
+ # @param offer_id [Integer] the offer ID to modify (0 to create a new offer)
350
+ #
351
+ # @return [Operation] the built operation
352
+ def manage_buy_offer(buying:, selling:, amount:, price:, offer_id: 0, source_account: nil)
353
+ buying = Asset.send(*buying) if buying.is_a?(Array)
354
+ selling = Asset.send(*selling) if selling.is_a?(Array)
299
355
 
300
- op = ManageBuyOfferOp.new({
356
+ op = ManageBuyOfferOp.new(
301
357
  buying: buying,
302
358
  selling: selling,
303
- amount: amount,
304
- price: price,
359
+ buy_amount: interpret_amount(amount),
360
+ price: Price.from(price),
305
361
  offer_id: offer_id
306
- })
362
+ )
307
363
 
308
- make(attributes.merge({
309
- body: [:manage_buy_offer, op]
310
- }))
364
+ make(source_account: source_account, body: [:manage_buy_offer, op])
311
365
  end
312
366
 
313
- def create_passive_sell_offer(attributes = {})
314
- buying = attributes[:buying]
315
- if buying.is_a?(Array)
316
- buying = Asset.send(*buying)
317
- end
318
- selling = attributes[:selling]
319
- if selling.is_a?(Array)
320
- selling = Asset.send(*selling)
321
- end
322
- amount = interpret_amount(attributes[:amount])
323
- price = interpret_price(attributes[:price])
367
+ # Create Passive Sell Offer operation builder
368
+ #
369
+ # @param source_account [KeyPair, nil] the source account for the operation
370
+ # @param selling [Asset] the asset to sell
371
+ # @param buying [Asset] the asset to buy
372
+ # @param amount [String, Numeric] the amount of asset to sell
373
+ # @param price [String, Numeric, Price] the price of the selling asset in terms of buying asset
374
+ #
375
+ # @return [Operation] the built operation
376
+ def create_passive_sell_offer(selling:, buying:, amount:, price:, source_account: nil)
377
+ selling = Asset.send(*selling) if selling.is_a?(Array)
378
+ buying = Asset.send(*buying) if buying.is_a?(Array)
324
379
 
325
- op = CreatePassiveSellOfferOp.new({
380
+ op = CreatePassiveSellOfferOp.new(
326
381
  buying: buying,
327
382
  selling: selling,
328
- amount: amount,
329
- price: price
330
- })
383
+ amount: interpret_amount(amount),
384
+ price: Price.from(price)
385
+ )
331
386
 
332
- make(attributes.merge({
333
- body: [:create_passive_sell_offer, op]
334
- }))
387
+ make(source_account: source_account, body: [:create_passive_sell_offer, op])
335
388
  end
336
389
 
390
+ # Liquidity Pool Deposit operation builder
337
391
  #
338
- # Helper method to create a valid SetOptionsOp, wrapped
339
- # in the necessary XDR structs to be included within a
340
- # transactions `operations` array.
341
- #
342
- # @param [Hash] attributes the attributes to create the operation with
343
- # @option attributes [Stellar::KeyPair] :inflation_dest
344
- # @option attributes [Array<Stellar::AccountFlags>] :set flags to set
345
- # @option attributes [Array<Stellar::AccountFlags>] :clear flags to clear
346
- # @option attributes [String] :thresholds
347
- # @option attributes [Stellar::Signer] :signer
348
- #
349
- # @return [Stellar::Operation] the built operation, containing a
350
- # Stellar::SetOptionsOp body
351
- def set_options(attributes = {})
352
- op = SetOptionsOp.new
353
- op.set_flags = Stellar::AccountFlags.make_mask attributes[:set]
354
- op.clear_flags = Stellar::AccountFlags.make_mask attributes[:clear]
355
- op.master_weight = attributes[:master_weight]
356
- op.low_threshold = attributes[:low_threshold]
357
- op.med_threshold = attributes[:med_threshold]
358
- op.high_threshold = attributes[:high_threshold]
359
-
360
- op.signer = attributes[:signer]
361
- op.home_domain = attributes[:home_domain]
362
-
363
- inflation_dest = attributes[:inflation_dest]
364
- if inflation_dest
365
- raise ArgumentError, "Bad :inflation_dest" unless inflation_dest.is_a?(Stellar::KeyPair)
366
- op.inflation_dest = inflation_dest.account_id
367
- end
392
+ # @param [Stellar::KeyPair] source_account the source account for the operation
393
+ # @param [String] liquidity_pool_id the liquidity pool id as hexadecimal string
394
+ # @param [String, Numeric] max_amount_a the maximum amount of asset A to deposit
395
+ # @param [String, Numeric] max_amount_b the maximum amount of asset B to deposit
396
+ # @param [String, Numeric, Stellar::Price] min_price the minimum valid price of asset A in terms of asset B
397
+ # @param [String, Numeric, Stellar::Price] max_price the maximum valid price of asset A in terms of asset B
398
+ #
399
+ # @return [Stellar::Operation] the built operation
400
+ def liquidity_pool_deposit(liquidity_pool_id:, max_amount_a:, max_amount_b:, min_price:, max_price:, source_account: nil)
401
+ op = LiquidityPoolDepositOp.new(
402
+ liquidity_pool_id: PoolID.from_xdr(liquidity_pool_id, :hex),
403
+ max_amount_a: interpret_amount(max_amount_a),
404
+ max_amount_b: interpret_amount(max_amount_b),
405
+ min_price: Price.from(min_price),
406
+ max_price: Price.from(max_price)
407
+ )
368
408
 
369
- make(attributes.merge({
370
- body: [:set_options, op]
371
- }))
409
+ make(source_account: source_account, body: [:liquidity_pool_deposit, op])
410
+ rescue XDR::ReadError
411
+ raise ArgumentError, "invalid liquidity pool ID '#{balance_id}'"
372
412
  end
373
413
 
414
+ # Liquidity Pool Withdraw operation builder
374
415
  #
375
- # Helper method to create a valid AllowTrustOp, wrapped
376
- # in the necessary XDR structs to be included within a
377
- # transactions `operations` array.
416
+ # @param [Stellar::KeyPair] source_account the source account for the operation
417
+ # @param [String] liquidity_pool_id the liquidity pool id as hexadecimal string
418
+ # @param [String, Numeric] amount the number of pool shares to withdraw
419
+ # @param [String, Numeric] min_amount_a the minimum amount of asset A to withdraw
420
+ # @param [String, Numeric] min_amount_b the minimum amount of asset B to withdraw
378
421
  #
379
- # @param [Hash] attributes the attributes to create the operation with
380
- # @option attributes [Stellar::KeyPair] :trustor
381
- # @option attributes [Stellar::Asset] :asset
382
- # @option attributes [Symbol, Boolean] :authorize :full, maintain_liabilities or :none
383
- #
384
- # @return [Stellar::Operation] the built operation, containing a
385
- # Stellar::AllowTrustOp body
386
- def allow_trust(attributes = {})
387
- op = AllowTrustOp.new
388
-
389
- trustor = attributes[:trustor]
390
- authorize = attributes[:authorize]
391
- asset = attributes[:asset]
392
- if asset.is_a?(Array)
393
- asset = Asset.send(*asset)
394
- end
395
-
396
- raise ArgumentError, "Bad :trustor" unless trustor.is_a?(Stellar::KeyPair)
397
-
398
- op.authorize = case authorize
399
- when :none, false then 0 # we handle booleans here for the backward compatibility
400
- when :full, true then TrustLineFlags.authorized_flag.value
401
- when :maintain_liabilities then TrustLineFlags.authorized_to_maintain_liabilities_flag.value
402
- else
403
- raise ArgumentError, "Bad :authorize, supported values: :full, :maintain_liabilities, :none"
404
- end
405
-
406
- raise ArgumentError, "Bad :asset" unless asset.type == Stellar::AssetType.asset_type_credit_alphanum4
407
-
408
- atc = AllowTrustOp::Asset.new(:asset_type_credit_alphanum4, asset.code)
409
-
410
- op.trustor = trustor.account_id
411
- op.asset = atc
422
+ # @return [Stellar::Operation] the built operation
423
+ def liquidity_pool_withdraw(liquidity_pool_id:, amount:, min_amount_a:, min_amount_b:, source_account: nil)
424
+ op = LiquidityPoolWithdrawOp.new(
425
+ liquidity_pool_id: PoolID.from_xdr(liquidity_pool_id, :hex),
426
+ amount: interpret_amount(amount),
427
+ min_amount_a: interpret_amount(min_amount_a),
428
+ min_amount_b: interpret_amount(min_amount_b)
429
+ )
412
430
 
413
- make(attributes.merge({
414
- body: [:allow_trust, op]
415
- }))
431
+ make(source_account: source_account, body: [:liquidity_pool_withdraw, op])
432
+ rescue XDR::ReadError
433
+ raise ArgumentError, "invalid liquidity pool ID '#{balance_id}'"
416
434
  end
417
435
 
436
+ # Begin Sponsoring Future Reserves operation builder
418
437
  #
419
- # Helper method to create an account merge operation
420
- #
421
- # @param [Hash] attributes the attributes to create the operation with
422
- # @option attributes [Stellar::KeyPair] :destination
438
+ # @param source_account [KeyPair, nil] the source account for the operation
423
439
  #
424
- # @return [Stellar::Operation] the built operation
425
- def account_merge(attributes = {})
426
- destination = attributes[:destination]
427
-
428
- raise ArgumentError, "Bad :destination" unless destination.is_a?(KeyPair)
440
+ # @return [Operation] the built operation
441
+ def begin_sponsoring_future_reserves(sponsored:, source_account: nil)
442
+ op = BeginSponsoringFutureReservesOp.new(
443
+ sponsored_id: KeyPair(sponsored).account_id
444
+ )
429
445
 
430
- # TODO: add source_account support
431
- make(attributes.merge({
432
- body: [:account_merge, destination.muxed_account]
433
- }))
446
+ make(source_account: source_account, body: [:begin_sponsoring_future_reserves, op])
434
447
  end
435
448
 
449
+ # End Sponsoring Future Reserves operation builder
436
450
  #
437
- # Helper method to create an inflation operation
438
- #
439
- # @param [Hash] attributes the attributes to create the operation with
440
- # @option attributes [Integer] :sequence
451
+ # @param source_account [KeyPair, nil] the source account for the operation
441
452
  #
442
- # @return [Stellar::Operation] the built operation
443
- def inflation(attributes = {})
444
- sequence = attributes[:sequence]
445
-
446
- raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
447
-
448
- # TODO: add source_account support
449
- make(attributes.merge({
450
- body: [:inflation]
451
- }))
453
+ # @return [Operation] the built operation
454
+ def end_sponsoring_future_reserves(source_account: nil)
455
+ make(source_account: source_account, body: [:end_sponsoring_future_reserves])
452
456
  end
453
457
 
458
+ # Revoke Sponsorship operation builder
454
459
  #
455
- # Helper method to create an manage data operation
456
- #
457
- # @param [Hash] attributes the attributes to create the operation with
458
- # @option attributes [Integer] :sequence
460
+ # @param source_account [KeyPair, nil] the source account for the operation
461
+ # @param sponsored [#to_keypair] owner of sponsored entry
459
462
  #
460
- # @return [Stellar::Operation] the built operation
461
- def manage_data(attributes = {})
462
- op = ManageDataOp.new
463
-
464
- name = attributes[:name]
465
- value = attributes[:value]
466
-
467
- raise ArgumentError, "Invalid :name" unless name.is_a?(String)
468
- raise ArgumentError, ":name too long" unless name.bytesize <= 64
469
-
470
- if value.present?
471
- raise ArgumentError, ":value too long" unless value.bytesize <= 64
463
+ # @return [Operation] the built operation
464
+ def revoke_sponsorship(sponsored:, source_account: nil, **attributes)
465
+ key_fields = attributes.slice(:offer_id, :data_name, :balance_id, :liquidity_pool_id, :asset, :signer)
466
+ raise ArgumentError, "conflicting attributes: #{key_fields.keys.join(", ")}" if key_fields.size > 1
467
+ account_id = KeyPair(sponsored).account_id
468
+ key, value = key_fields.first
469
+ op = if key == :signer
470
+ RevokeSponsorshipOp.signer(account_id: account_id, signer_key: SignerKey(value))
471
+ else
472
+ RevokeSponsorshipOp.ledger_key(LedgerKey.from(account_id: account_id, **key_fields))
472
473
  end
473
-
474
- op.data_name = name
475
- op.data_value = value
476
-
477
- make(attributes.merge({
478
- body: [:manage_data, op]
479
- }))
474
+ make(source_account: source_account, body: [:revoke_sponsorship, op])
480
475
  end
481
476
 
482
- def bump_sequence(attributes = {})
483
- op = BumpSequenceOp.new
484
-
485
- bump_to = attributes[:bump_to]
486
-
487
- raise ArgumentError, ":bump_to too big" unless bump_to <= MAX_INT64
488
-
489
- op.bump_to = bump_to
490
-
491
- make(attributes.merge({
492
- body: [:bump_sequence, op]
493
- }))
477
+ # Inflation operation builder
478
+ #
479
+ # @param [Stellar::KeyPair, nil] source_account the source account for the operation
480
+ #
481
+ # @return [Stellar::Operation] the built operation
482
+ def inflation(source_account: nil)
483
+ make(source_account: source_account, body: [:inflation])
494
484
  end
495
485
 
496
486
  private
@@ -507,29 +497,10 @@ module Stellar
507
497
  end
508
498
 
509
499
  def interpret_amount(amount)
510
- case amount
511
- when String
512
- (BigDecimal(amount) * Stellar::ONE).floor
513
- when Integer
514
- amount * Stellar::ONE
515
- when Numeric
500
+ if amount.is_a?(Float)
516
501
  (amount * Stellar::ONE).floor
517
502
  else
518
- raise ArgumentError, "Invalid amount type: #{amount.class}. Must be String or Numeric"
519
- end
520
- end
521
-
522
- def interpret_price(price)
523
- case price
524
- when String
525
- bd = BigDecimal(price)
526
- Price.from_f(bd)
527
- when Numeric
528
- Price.from_f(price)
529
- when Stellar::Price
530
- price
531
- else
532
- raise ArgumentError, "Invalid price type: #{price.class}. Must be String, Numeric, or Stellar::Price"
503
+ (BigDecimal(amount) * Stellar::ONE).floor
533
504
  end
534
505
  end
535
506
  end