stellar-base 0.25.0 → 0.29.0

Sign up to get free protection for your applications and to get access to all the features.
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