stellar-base 0.25.0 → 0.29.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -31
  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/asset_code.rb +30 -0
  8. data/generated/stellar/begin_sponsoring_future_reserves_result.rb +2 -1
  9. data/generated/stellar/claimable_balance_entry/ext.rb +4 -0
  10. data/generated/stellar/claimable_balance_entry.rb +2 -0
  11. data/generated/stellar/claimable_balance_entry_extension_v1/ext.rb +24 -0
  12. data/generated/stellar/claimable_balance_entry_extension_v1.rb +30 -0
  13. data/generated/stellar/claimable_balance_flags.rb +22 -0
  14. data/generated/stellar/clawback_claimable_balance_op.rb +18 -0
  15. data/generated/stellar/clawback_claimable_balance_result.rb +26 -0
  16. data/generated/stellar/clawback_claimable_balance_result_code.rb +29 -0
  17. data/generated/stellar/clawback_op.rb +22 -0
  18. data/generated/stellar/clawback_result.rb +25 -0
  19. data/generated/stellar/clawback_result_code.rb +31 -0
  20. data/generated/stellar/create_passive_sell_offer_op.rb +1 -1
  21. data/generated/stellar/end_sponsoring_future_reserves_result.rb +2 -1
  22. data/generated/stellar/operation/body.rb +12 -0
  23. data/generated/stellar/operation.rb +6 -0
  24. data/generated/stellar/operation_id/id.rb +2 -2
  25. data/generated/stellar/operation_id.rb +1 -1
  26. data/generated/stellar/operation_result/tr.rb +12 -0
  27. data/generated/stellar/operation_result.rb +6 -0
  28. data/generated/stellar/operation_type.rb +7 -1
  29. data/generated/stellar/payment_result_code.rb +1 -1
  30. data/generated/stellar/revoke_sponsorship_op.rb +1 -2
  31. data/generated/stellar/set_options_result_code.rb +14 -11
  32. data/generated/stellar/set_trust_line_flags_op.rb +25 -0
  33. data/generated/stellar/set_trust_line_flags_result.rb +25 -0
  34. data/generated/stellar/set_trust_line_flags_result_code.rb +31 -0
  35. data/generated/stellar/transaction_result_code.rb +1 -1
  36. data/generated/stellar/trust_line_flags.rb +5 -1
  37. data/generated/stellar-base-generated.rb +15 -0
  38. data/lib/stellar/account.rb +59 -0
  39. data/lib/stellar/compat.rb +6 -3
  40. data/lib/stellar/concerns/transaction.rb +4 -2
  41. data/lib/stellar/dsl.rb +23 -0
  42. data/lib/stellar/operation.rb +85 -16
  43. data/lib/stellar/transaction_builder.rb +20 -7
  44. data/lib/stellar/trust_line_flags.rb +53 -0
  45. data/lib/stellar/util/strkey.rb +15 -7
  46. data/lib/stellar/version.rb +3 -0
  47. data/lib/stellar-base.rb +3 -2
  48. metadata +28 -12
  49. data/generated/stellar/allow_trust_op/asset.rb +0 -33
  50. data/lib/stellar/base/version.rb +0 -5
@@ -0,0 +1,31 @@
1
+ # This code was automatically generated using xdrgen
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # enum SetTrustLineFlagsResultCode
9
+ # {
10
+ # // codes considered as "success" for the operation
11
+ # SET_TRUST_LINE_FLAGS_SUCCESS = 0,
12
+ #
13
+ # // codes considered as "failure" for the operation
14
+ # SET_TRUST_LINE_FLAGS_MALFORMED = -1,
15
+ # SET_TRUST_LINE_FLAGS_NO_TRUST_LINE = -2,
16
+ # SET_TRUST_LINE_FLAGS_CANT_REVOKE = -3,
17
+ # SET_TRUST_LINE_FLAGS_INVALID_STATE = -4
18
+ # };
19
+ #
20
+ # ===========================================================================
21
+ module Stellar
22
+ class SetTrustLineFlagsResultCode < XDR::Enum
23
+ member :set_trust_line_flags_success, 0
24
+ member :set_trust_line_flags_malformed, -1
25
+ member :set_trust_line_flags_no_trust_line, -2
26
+ member :set_trust_line_flags_cant_revoke, -3
27
+ member :set_trust_line_flags_invalid_state, -4
28
+
29
+ seal
30
+ end
31
+ end
@@ -22,7 +22,7 @@ require 'xdr'
22
22
  # txNO_ACCOUNT = -8, // source account not found
23
23
  # txINSUFFICIENT_FEE = -9, // fee is too small
24
24
  # txBAD_AUTH_EXTRA = -10, // unused signatures attached to transaction
25
- # txINTERNAL_ERROR = -11, // an unknown error occured
25
+ # txINTERNAL_ERROR = -11, // an unknown error occurred
26
26
  #
27
27
  # txNOT_SUPPORTED = -12, // transaction type not supported
28
28
  # txFEE_BUMP_INNER_FAILED = -13, // fee bump inner transaction failed
@@ -11,7 +11,10 @@ require 'xdr'
11
11
  # AUTHORIZED_FLAG = 1,
12
12
  # // issuer has authorized account to maintain and reduce liabilities for its
13
13
  # // credit
14
- # AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG = 2
14
+ # AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG = 2,
15
+ # // issuer has specified that it may clawback its credit, and that claimable
16
+ # // balances created with its credit may also be clawed back
17
+ # TRUSTLINE_CLAWBACK_ENABLED_FLAG = 4
15
18
  # };
16
19
  #
17
20
  # ===========================================================================
@@ -19,6 +22,7 @@ module Stellar
19
22
  class TrustLineFlags < XDR::Enum
20
23
  member :authorized_flag, 1
21
24
  member :authorized_to_maintain_liabilities_flag, 2
25
+ member :trustline_clawback_enabled_flag, 4
22
26
 
23
27
  seal
24
28
  end
@@ -38,6 +38,7 @@ module Stellar
38
38
  AssetCode4 = XDR::Opaque[4]
39
39
  AssetCode12 = XDR::Opaque[12]
40
40
  autoload :AssetType
41
+ autoload :AssetCode
41
42
  autoload :Asset
42
43
  autoload :Price
43
44
  autoload :Liabilities
@@ -46,6 +47,7 @@ module Stellar
46
47
  autoload :Signer
47
48
  autoload :AccountFlags
48
49
  MASK_ACCOUNT_FLAGS = 0x7
50
+ MASK_ACCOUNT_FLAGS_V17 = 0xF
49
51
  MAX_SIGNERS = 20
50
52
  SponsorshipDescriptor = XDR::Option[AccountID]
51
53
  autoload :AccountEntryExtensionV2
@@ -54,6 +56,7 @@ module Stellar
54
56
  autoload :TrustLineFlags
55
57
  MASK_TRUSTLINE_FLAGS = 1
56
58
  MASK_TRUSTLINE_FLAGS_V13 = 3
59
+ MASK_TRUSTLINE_FLAGS_V17 = 7
57
60
  autoload :TrustLineEntry
58
61
  autoload :OfferEntryFlags
59
62
  MASK_OFFERENTRY_FLAGS = 1
@@ -65,6 +68,9 @@ module Stellar
65
68
  autoload :Claimant
66
69
  autoload :ClaimableBalanceIDType
67
70
  autoload :ClaimableBalanceID
71
+ autoload :ClaimableBalanceFlags
72
+ MASK_CLAIMABLE_BALANCE_FLAGS = 0x1
73
+ autoload :ClaimableBalanceEntryExtensionV1
68
74
  autoload :ClaimableBalanceEntry
69
75
  autoload :LedgerEntryExtensionV1
70
76
  autoload :LedgerEntry
@@ -94,6 +100,9 @@ module Stellar
94
100
  autoload :BeginSponsoringFutureReservesOp
95
101
  autoload :RevokeSponsorshipType
96
102
  autoload :RevokeSponsorshipOp
103
+ autoload :ClawbackOp
104
+ autoload :ClawbackClaimableBalanceOp
105
+ autoload :SetTrustLineFlagsOp
97
106
  autoload :Operation
98
107
  autoload :OperationID
99
108
  autoload :MemoType
@@ -149,6 +158,12 @@ module Stellar
149
158
  autoload :EndSponsoringFutureReservesResult
150
159
  autoload :RevokeSponsorshipResultCode
151
160
  autoload :RevokeSponsorshipResult
161
+ autoload :ClawbackResultCode
162
+ autoload :ClawbackResult
163
+ autoload :ClawbackClaimableBalanceResultCode
164
+ autoload :ClawbackClaimableBalanceResult
165
+ autoload :SetTrustLineFlagsResultCode
166
+ autoload :SetTrustLineFlagsResult
152
167
  autoload :OperationResultCode
153
168
  autoload :OperationResult
154
169
  autoload :TransactionResultCode
@@ -0,0 +1,59 @@
1
+ module Stellar
2
+ class Account
3
+ delegate :address, to: :keypair
4
+
5
+ def self.random
6
+ keypair = Stellar::KeyPair.random
7
+ new(keypair)
8
+ end
9
+
10
+ def self.from_seed(seed)
11
+ keypair = Stellar::KeyPair.from_seed(seed)
12
+ new(keypair)
13
+ end
14
+
15
+ def self.from_address(address)
16
+ muxed_xdr = Util::StrKey.decode_muxed_account(address)
17
+
18
+ if muxed_xdr.ed25519
19
+ new(KeyPair.from_public_key(muxed_xdr.ed25519))
20
+ else
21
+ muxed_xdr = muxed_xdr.med25519!
22
+ new(KeyPair.from_public_key(muxed_xdr.ed25519), muxed_xdr.id)
23
+ end
24
+ end
25
+
26
+ def self.master
27
+ keypair = Stellar::KeyPair.from_raw_seed("allmylifemyhearthasbeensearching")
28
+ new(keypair)
29
+ end
30
+
31
+ attr_reader :keypair, :id
32
+
33
+ # @param [Stellar::KeyPair] keypair
34
+ # @param [Integer] id
35
+ def initialize(keypair, id = nil)
36
+ @keypair = keypair
37
+ @id = id
38
+ end
39
+
40
+ def base_account
41
+ Stellar::MuxedAccount.ed25519(keypair.raw_public_key)
42
+ end
43
+
44
+ def muxed_account
45
+ return base_account unless id
46
+ Stellar::MuxedAccount.med25519(ed25519: keypair.raw_public_key, id: id)
47
+ end
48
+
49
+ def address(force_account_id: true)
50
+ return keypair.address if force_account_id
51
+
52
+ Util::StrKey.check_encode(:muxed, keypair.raw_public_key + [id].pack("Q>"))
53
+ end
54
+
55
+ def to_keypair
56
+ keypair
57
+ end
58
+ end
59
+ end
@@ -2,7 +2,10 @@ class << Stellar::Operation
2
2
  alias_method :manage_offer, :manage_sell_offer
3
3
  alias_method :create_passive_offer, :create_passive_sell_offer
4
4
 
5
- deprecate deprecator: Stellar::Deprecation,
6
- manage_offer: :manage_sell_offer,
7
- create_passive_offer: :create_passive_sell_offer
5
+ deprecate(
6
+ deprecator: Stellar::Deprecation,
7
+ manage_offer: :manage_sell_offer,
8
+ create_passive_offer: :create_passive_sell_offer,
9
+ allow_trust: :set_trust_line_flags
10
+ )
8
11
  end
@@ -19,7 +19,7 @@ module Stellar::Concerns
19
19
  end
20
20
 
21
21
  def merge(other)
22
- cloned = Marshal.load Marshal.dump(self)
22
+ cloned = from_xdr(to_xdr)
23
23
  cloned.operations += other.to_operations
24
24
  cloned
25
25
  end
@@ -32,7 +32,9 @@ module Stellar::Concerns
32
32
  #
33
33
  # @return [Array<Operation>] the operations
34
34
  def to_operations
35
- cloned = Marshal.load Marshal.dump(operations)
35
+ codec = XDR::VarArray[Stellar::Operation]
36
+ ops = respond_to?(:operations) ? operations : inner_tx.value.tx.operations
37
+ cloned = codec.from_xdr(codec.to_xdr(ops))
36
38
  cloned.each do |op|
37
39
  op.source_account ||= source_account
38
40
  end
data/lib/stellar/dsl.rb CHANGED
@@ -27,6 +27,28 @@ module Stellar
27
27
  )
28
28
  end
29
29
 
30
+ def Account(subject = nil)
31
+ case subject
32
+ when Account
33
+ subject
34
+ when /^M[A-Z0-9]{68}$/
35
+ Account.from_address(subject.to_str)
36
+ when nil
37
+ Account.random
38
+ else
39
+ begin
40
+ keypair = KeyPair(subject)
41
+
42
+ Account.new(keypair)
43
+ rescue TypeError
44
+ raise TypeError, "Cannot convert #{subject.inspect} to Stellar::Account"
45
+ end
46
+ end
47
+ end
48
+
49
+ # @param [Asset, String, nil] subject
50
+ # @return [Stellar::Asset] instance of the Stellar::Asset
51
+ # @raise [TypeError] if subject cannot be converted to Stellar::Asset
30
52
  def Asset(subject = nil)
31
53
  case subject
32
54
  when Asset
@@ -45,6 +67,7 @@ module Stellar
45
67
  # Generates Stellar::Keypair from subject, use Stellar::Client.to_keypair as shortcut.
46
68
  # @param subject [String|Stellar::Account|Stellar::PublicKey|Stellar::SignerKey|Stellar::Keypair] subject.
47
69
  # @return [Stellar::Keypair] Stellar::Keypair instance.
70
+ # @raise [TypeError] if subject cannot be converted to Stellar::KeyPair
48
71
  def KeyPair(subject = nil)
49
72
  case subject
50
73
  when ->(subj) { subj.respond_to?(:to_keypair) }
@@ -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
@@ -17,16 +22,17 @@ module Stellar
17
22
  # @return [Stellar::Operation] the built operation
18
23
  def make(attributes = {})
19
24
  source_account = attributes[:source_account]
20
- body = Stellar::Operation::Body.new(*attributes[:body])
21
-
22
- op = Stellar::Operation.new(body: body)
23
25
 
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
26
+ if source_account && !source_account.is_a?(Stellar::KeyPair)
27
+ raise ArgumentError, "Bad :source_account"
27
28
  end
28
29
 
29
- op
30
+ body = Stellar::Operation::Body.new(*attributes[:body])
31
+
32
+ Stellar::Operation.new(
33
+ body: body,
34
+ source_account: source_account&.muxed_account
35
+ )
30
36
  end
31
37
 
32
38
  #
@@ -300,7 +306,7 @@ module Stellar
300
306
  op = ManageBuyOfferOp.new({
301
307
  buying: buying,
302
308
  selling: selling,
303
- amount: amount,
309
+ buy_amount: amount,
304
310
  price: price,
305
311
  offer_id: offer_id
306
312
  })
@@ -371,11 +377,31 @@ module Stellar
371
377
  }))
372
378
  end
373
379
 
380
+ # @param asset [Stellar::Asset]
381
+ # @param trustor [Stellar::KeyPair]
382
+ # @param flags [{String, Symbol, Stellar::TrustLineFlags => true, false}] flags to to set or clear
383
+ # @param source_account [Stellar::KeyPair] source account (default is `nil`, which will use the source account of transaction)
384
+ def set_trust_line_flags(asset:, trustor:, flags: {}, source_account: nil)
385
+ op = Stellar::SetTrustLineFlagsOp.new
386
+ op.trustor = KeyPair(trustor).account_id
387
+ op.asset = Asset(asset)
388
+ op.attributes = Stellar::TrustLineFlags.set_clear_masks(flags)
389
+
390
+ make(
391
+ source_account: source_account,
392
+ body: [:set_trust_line_flags, op]
393
+ )
394
+ end
395
+
396
+ # DEPRECATED in favor of `set_trustline_flags`
374
397
  #
375
398
  # Helper method to create a valid AllowTrustOp, wrapped
376
399
  # in the necessary XDR structs to be included within a
377
400
  # transactions `operations` array.
378
401
  #
402
+ # @deprecated Use `set_trustline_flags` operation
403
+ # See {https://github.com/stellar/stellar-protocol/blob/master/core/cap-0035.md#allow-trust-operation-1 CAP-35 description}
404
+ # for more details
379
405
  # @param [Hash] attributes the attributes to create the operation with
380
406
  # @option attributes [Stellar::KeyPair] :trustor
381
407
  # @option attributes [Stellar::Asset] :asset
@@ -387,7 +413,8 @@ module Stellar
387
413
  op = AllowTrustOp.new
388
414
 
389
415
  trustor = attributes[:trustor]
390
- authorize = attributes[:authorize]
416
+ # we handle booleans here for the backward compatibility
417
+ authorize = attributes[:authorize].yield_self { |value| value == true ? :full : value }
391
418
  asset = attributes[:asset]
392
419
  if asset.is_a?(Array)
393
420
  asset = Asset.send(*asset)
@@ -395,20 +422,21 @@ module Stellar
395
422
 
396
423
  raise ArgumentError, "Bad :trustor" unless trustor.is_a?(Stellar::KeyPair)
397
424
 
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
425
+ allowed_flags = TRUST_LINE_FLAGS_MAPPING.slice(:full, :maintain_liabilities)
426
+
427
+ # we handle booleans here for the backward compatibility
428
+ op.authorize = if allowed_flags.key?(authorize)
429
+ allowed_flags[authorize].value
430
+ elsif [:none, false].include?(authorize)
431
+ 0
402
432
  else
403
433
  raise ArgumentError, "Bad :authorize, supported values: :full, :maintain_liabilities, :none"
404
434
  end
405
435
 
406
436
  raise ArgumentError, "Bad :asset" unless asset.type == Stellar::AssetType.asset_type_credit_alphanum4
407
437
 
408
- atc = AllowTrustOp::Asset.new(:asset_type_credit_alphanum4, asset.code)
409
-
410
438
  op.trustor = trustor.account_id
411
- op.asset = atc
439
+ op.asset = AssetCode.new(:asset_type_credit_alphanum4, asset.code)
412
440
 
413
441
  make(attributes.merge({
414
442
  body: [:allow_trust, op]
@@ -493,6 +521,47 @@ module Stellar
493
521
  }))
494
522
  end
495
523
 
524
+ def clawback(source_account:, from:, amount:)
525
+ asset, amount = get_asset_amount(amount)
526
+
527
+ if amount == 0
528
+ raise ArgumentError, "Amount can not be zero"
529
+ end
530
+
531
+ if amount < 0
532
+ raise ArgumentError, "Negative amount is not allowed"
533
+ end
534
+
535
+ op = ClawbackOp.new(
536
+ amount: amount,
537
+ from: from.muxed_account,
538
+ asset: asset
539
+ )
540
+
541
+ make({
542
+ source_account: source_account,
543
+ body: [:clawback, op]
544
+ })
545
+ end
546
+
547
+ # Helper method to create clawback claimable balance operation
548
+ #
549
+ # @param [Stellar::KeyPair] source_account the attributes to create the operation with
550
+ # @param [String] balance_id `ClaimableBalanceID`, serialized in hex
551
+ #
552
+ # @return [Stellar::Operation] the built operation
553
+ def clawback_claimable_balance(source_account:, balance_id:)
554
+ balance_id = Stellar::ClaimableBalanceID.from_xdr(balance_id, :hex)
555
+ op = ClawbackClaimableBalanceOp.new(balance_id: balance_id)
556
+
557
+ make(
558
+ source_account: source_account,
559
+ body: [:clawback_claimable_balance, op]
560
+ )
561
+ rescue XDR::ReadError
562
+ raise ArgumentError, "Claimable balance id '#{balance_id}' is invalid"
563
+ end
564
+
496
565
  private
497
566
 
498
567
  def get_asset_amount(values)
@@ -1,5 +1,7 @@
1
1
  module Stellar
2
2
  class TransactionBuilder
3
+ include Stellar::DSL
4
+
3
5
  attr_reader :source_account, :sequence_number, :base_fee, :time_bounds, :memo, :operations
4
6
 
5
7
  class << self
@@ -29,21 +31,20 @@ module Stellar
29
31
  base_fee: 100,
30
32
  time_bounds: nil,
31
33
  memo: nil,
34
+ enable_muxed_accounts: false,
32
35
  **_ # ignore any additional parameters without errors
33
36
  )
34
- raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
35
37
  raise ArgumentError, "Bad :sequence_number" unless sequence_number.is_a?(Integer) && sequence_number >= 0
36
38
  raise ArgumentError, "Bad :time_bounds" unless time_bounds.is_a?(Stellar::TimeBounds) || time_bounds.nil?
37
39
  raise ArgumentError, "Bad :base_fee" unless base_fee.is_a?(Integer) && base_fee >= 100
38
40
 
39
- @source_account = source_account
41
+ @source_account = Account(source_account)
40
42
  @sequence_number = sequence_number
41
43
  @base_fee = base_fee
42
44
  @time_bounds = time_bounds
45
+ @enable_muxed_accounts = enable_muxed_accounts
43
46
 
44
- if time_bounds.nil?
45
- set_timeout(0)
46
- end
47
+ set_timeout(0) if time_bounds.nil?
47
48
 
48
49
  @memo = make_memo(memo)
49
50
  @operations = []
@@ -59,7 +60,7 @@ module Stellar
59
60
  end
60
61
 
61
62
  attrs = {
62
- source_account: @source_account.muxed_account,
63
+ source_account: source_muxed_account,
63
64
  fee: @base_fee * @operations.length,
64
65
  seq_num: @sequence_number,
65
66
  time_bounds: @time_bounds,
@@ -90,7 +91,7 @@ module Stellar
90
91
  end
91
92
 
92
93
  Stellar::FeeBumpTransaction.new(
93
- fee_source: @source_account.muxed_account,
94
+ fee_source: source_muxed_account,
94
95
  fee: @base_fee * (inner_ops.length + 1),
95
96
  inner_tx: Stellar::FeeBumpTransaction::InnerTx.new(:envelope_type_tx, inner_txe.v1!),
96
97
  ext: Stellar::FeeBumpTransaction::Ext.new(0)
@@ -162,5 +163,17 @@ module Stellar
162
163
  raise ArgumentError, "Bad :memo"
163
164
  end
164
165
  end
166
+
167
+ def source_muxed_account
168
+ if with_muxed_accounts?
169
+ @source_account.muxed_account
170
+ else
171
+ @source_account.base_account
172
+ end
173
+ end
174
+
175
+ def with_muxed_accounts?
176
+ @enable_muxed_accounts
177
+ end
165
178
  end
166
179
  end