stellar-base 0.23.0 → 0.26.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +114 -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 +162 -30
  79. data/generated/stellar/account_entry/ext/v1.rb +0 -34
  80. data/lib/stellar/util/continued_fraction.rb +0 -96
@@ -4,7 +4,7 @@ module Stellar
4
4
  # Converts an array of Stellar::AccountFlags members into
5
5
  # an Integer suitable for use in a SetOptionsOp.
6
6
  #
7
- # @param flags=nil [Array<Stellar::AccountFlags>] the flags to combine
7
+ # @param flags [Array<Stellar::AccountFlags>] the flags to combine
8
8
  #
9
9
  # @return [Fixnum] the combined result
10
10
  def self.make_mask(flags = nil)
data/lib/stellar/asset.rb CHANGED
@@ -6,14 +6,24 @@ module Stellar
6
6
  new(:asset_type_native)
7
7
  end
8
8
 
9
+ # @param code [String] asset code
10
+ # @param issuer [#to_keypair] asset issuer
11
+ #
12
+ # @return [Stellar::Asset::AlphaNum4] asset4 representation
9
13
  def self.alphanum4(code, issuer)
14
+ issuer = issuer.to_keypair if issuer.respond_to?(:to_keypair)
10
15
  raise ArgumentError, "Bad :issuer" unless issuer.is_a?(KeyPair)
11
16
  code = normalize_code(code, 4)
12
17
  an = AlphaNum4.new({asset_code: code, issuer: issuer.account_id})
13
18
  new(:asset_type_credit_alphanum4, an)
14
19
  end
15
20
 
21
+ # @param code [String] asset code
22
+ # @param issuer [#to_keypair] asset issuer
23
+ #
24
+ # @return [Stellar::Asset::AlphaNum4] asset4 representation
16
25
  def self.alphanum12(code, issuer)
26
+ issuer = issuer.to_keypair if issuer.respond_to?(:to_keypair)
17
27
  raise ArgumentError, "Bad :issuer" unless issuer.is_a?(KeyPair)
18
28
  code = normalize_code(code, 12)
19
29
  an = AlphaNum12.new({asset_code: code, issuer: issuer.account_id})
@@ -1,5 +1,5 @@
1
1
  module Stellar
2
2
  module Base
3
- VERSION = "0.23.0"
3
+ VERSION = "0.26.0"
4
4
  end
5
5
  end
@@ -0,0 +1,198 @@
1
+ # frozen_string_literals: true
2
+ require "active_support/core_ext/integer/time"
3
+ require "active_support/core_ext/string/conversions"
4
+
5
+ module Stellar
6
+ # Represents claim predicate on Stellar network.
7
+ #
8
+ # @see https://developers.stellar.org/docs/glossary/claimable-balance/
9
+ class ClaimPredicate
10
+ module FactoryMethods
11
+ # Constructs an `unconditional` claim predicate.
12
+ #
13
+ # This predicate will be always fulfilled.
14
+ #
15
+ # @return [ClaimPredicate] `unconditional` claim predicate
16
+ def unconditional
17
+ ClaimPredicate.new(ClaimPredicateType::UNCONDITIONAL)
18
+ end
19
+
20
+ # Constructs a `before_relative_time` claim predicate.
21
+ #
22
+ # This predicate will be fulfilled if the closing time of the ledger that includes
23
+ # the Stellar::CreateClaimableBalance operation plus this relative time delta (in seconds)
24
+ # is less than the current time.
25
+ #
26
+ # @param seconds [#to_int|#to_i] seconds since `closeTime` of the ledger in which
27
+ # the ClaimableBalanceEntry was created.
28
+ # @return [ClaimPredicate] `before_relative_time` claim predicate
29
+ def before_relative_time(seconds)
30
+ ClaimPredicate.new(ClaimPredicateType::BEFORE_RELATIVE_TIME, Integer(seconds))
31
+ end
32
+
33
+ # Constructs an `before_absolute_time` claim predicate.
34
+ #
35
+ # This predicate will be fulfilled if the closing time of the ledger that includes
36
+ # the Stellar::CreateClaimableBalance operation is less than provided timestamp.
37
+ #
38
+ # @param timestamp [#to_time|#to_int|#to_i] time value or timestamp
39
+ #
40
+ # @return [ClaimPredicate] `before_absolute_time` claim predicate.
41
+ def before_absolute_time(timestamp)
42
+ timestamp = timestamp.to_time if timestamp.respond_to?(:to_time)
43
+
44
+ ClaimPredicate.new(ClaimPredicateType::BEFORE_ABSOLUTE_TIME, Integer(timestamp))
45
+ end
46
+
47
+ # Constructs either relative or absolute time predicate based on the type of the input.
48
+ #
49
+ # If input is an instance of `ActiveSupport::Duration` class it will be handled as a relative time
50
+ # (seconds since close time of the ledger), otherwise it will be treated as an absolute time.
51
+ #
52
+ # It is intended to work with time helpers provided by ActiveSupport, like `1.day` (relative)
53
+ # or `2.weeks.from_now` (absolute).
54
+ #
55
+ # @example relative time
56
+ # ClaimPredicate.before(2.days + 15.seconds)
57
+ #
58
+ # @example absolute time
59
+ # ClaimPredicate.before(5.hours.from_now)
60
+ #
61
+ # @param time [ActiveSupport::Duration|#to_time|#to_i] duration since ledger close time or absolute time value
62
+ #
63
+ # @return [ClaimPredicate] `before_relative_time` or `before_absolute_time` claim predicate.
64
+ def before(time)
65
+ ActiveSupport::Duration === time ? before_relative_time(time.to_i) : before_absolute_time(time)
66
+ end
67
+
68
+ # Constructs a negated predicate from either relative or absolute time based on the type of the input.
69
+ #
70
+ # @see #before
71
+ # @param (see #before)
72
+ # @return (see #before)
73
+ def after(time)
74
+ ~before(time)
75
+ end
76
+
77
+ # Compose a complex predicate by calling DSL methods from the block.
78
+ #
79
+ # @example
80
+ # ClaimPredicate.compose {
81
+ # after(15.minutes) & before(1.day) | after(1.week.from_now) & before(1.week.from_now + 1.day)
82
+ # }
83
+ #
84
+ # @yieldreturn [ClaimPredicate|nil]
85
+ # @return [ClaimPredicate] `not(before_relative_time)` or `not(before_absolute_time)` claim predicate.
86
+ def compose(&block)
87
+ result = instance_eval(&block)
88
+ result.nil? ? unconditional : result
89
+ end
90
+ end
91
+
92
+ extend FactoryMethods
93
+
94
+ # Constructs an `and` claim predicate.
95
+ #
96
+ # This predicate will be fulfilled if both `self` and `other` predicates are fulfilled.
97
+ #
98
+ # @param other [ClaimPredicate] another predicate
99
+ #
100
+ # @return [ClaimPredicate] `and` claim predicate
101
+ def and(other)
102
+ raise TypeError, "no conversion from #{other.class.name} to ClaimPredicate" unless ClaimPredicate === other
103
+ ClaimPredicate.new(ClaimPredicateType::AND, [self, other])
104
+ end
105
+ alias_method :&, :and
106
+
107
+ # Constructs an `or` claim predicate.
108
+ #
109
+ # This predicate will be fulfilled if either of `self` or `other` predicates is fulfilled.
110
+ #
111
+ # @param other [ClaimPredicate] another predicate.
112
+ #
113
+ # @return [ClaimPredicate] `or` claim predicate
114
+ def or(other)
115
+ raise TypeError, "no conversion from #{other.class.name} to ClaimPredicate" unless ClaimPredicate === other
116
+ ClaimPredicate.new(ClaimPredicateType::OR, [self, other])
117
+ end
118
+ alias_method :|, :or
119
+
120
+ # Constructs a `not` claim predicate.
121
+ #
122
+ # This predicate will be fulfilled if `self` is not fulfilled.
123
+ #
124
+ # @return [ClaimPredicate] `not` claim predicate
125
+ def not
126
+ ClaimPredicate.new(ClaimPredicateType::NOT, self)
127
+ end
128
+ alias_method :~@, :not
129
+
130
+ # Evaluates the predicate value for provided inputs.
131
+ #
132
+ # @param created_at [#to_time|#to_int] closing time of the ledger containing CreateClaimableBalance operation
133
+ # @param claiming_at [#to_time|#to_int|ActiveSupport::Duration] time point to evaluate predicate at, either
134
+ # absolute time or duration relative to `created_at`. In reality predicate will be evaluated by stellar-core
135
+ # using the closing time of a ledger containing ClaimClaimableBalance operation, in either successful
136
+ # or failed state.
137
+ #
138
+ # @return [Boolean] `true` if this predicate would allow claiming the balance, `false` otherwise
139
+ def evaluate(created_at, claiming_at)
140
+ created_at = created_at.to_time if created_at.respond_to?(:to_time)
141
+ claiming_at = created_at + claiming_at if claiming_at.is_a?(ActiveSupport::Duration)
142
+ claiming_at = claiming_at.to_time if claiming_at.respond_to?(:to_time)
143
+
144
+ return false if claiming_at < created_at
145
+
146
+ case switch
147
+ when ClaimPredicateType::UNCONDITIONAL
148
+ true
149
+ when ClaimPredicateType::BEFORE_RELATIVE_TIME
150
+ Integer(claiming_at) < Integer(created_at) + value
151
+ when ClaimPredicateType::BEFORE_ABSOLUTE_TIME
152
+ Integer(claiming_at).to_i < value
153
+ when ClaimPredicateType::AND
154
+ value[0].evaluate(created_at, claiming_at) && value[1].evaluate(created_at, claiming_at)
155
+ when ClaimPredicateType::OR
156
+ value[0].evaluate(created_at, claiming_at) || value[1].evaluate(created_at, claiming_at)
157
+ when ClaimPredicateType::NOT
158
+ !value.evaluate(created_at, claiming_at)
159
+ else
160
+ raise ArgumentError, "evaluation is not implemented for #{switch.name} predicate"
161
+ end
162
+ end
163
+
164
+ def describe
165
+ case switch
166
+ when ClaimPredicateType::UNCONDITIONAL
167
+ "always"
168
+ when ClaimPredicateType::BEFORE_RELATIVE_TIME
169
+ dur = ActiveSupport::Duration.build(value)
170
+ "less than #{dur.inspect} since creation"
171
+ when ClaimPredicateType::BEFORE_ABSOLUTE_TIME
172
+ "before #{Time.at(value).to_formatted_s(:db)}"
173
+ when ClaimPredicateType::AND
174
+ value.map(&:describe).join(" and ")
175
+ when ClaimPredicateType::OR
176
+ "(" << value.map(&:describe).join(" or ") << ")"
177
+ when ClaimPredicateType::NOT
178
+ case value.switch
179
+ when ClaimPredicateType::UNCONDITIONAL
180
+ "never"
181
+ when ClaimPredicateType::BEFORE_RELATIVE_TIME
182
+ dur = ActiveSupport::Duration.build(value.value)
183
+ "#{dur.inspect} or more since creation"
184
+ when ClaimPredicateType::BEFORE_ABSOLUTE_TIME
185
+ "after #{Time.at(value.value).to_formatted_s(:db)}"
186
+ else
187
+ "not (#{value.describe})"
188
+ end
189
+ else
190
+ raise ArgumentError, "evaluation is not implemented for #{switch.name} predicate"
191
+ end
192
+ end
193
+
194
+ def inspect
195
+ "#<ClaimPredicate: #{describe}>"
196
+ end
197
+ end
198
+ end
@@ -1,19 +1,6 @@
1
- require "active_support/deprecation"
2
-
3
- Stellar::Deprecation ||= ActiveSupport::Deprecation.new("next release", "stellar-base")
4
-
5
1
  class << Stellar::Operation
6
- alias manage_offer manage_sell_offer
7
- alias create_passive_offer create_passive_sell_offer
8
-
9
- deprecate deprecator: Stellar::Deprecation,
10
- manage_offer: :manage_sell_offer,
11
- create_passive_offer: :create_passive_sell_offer
12
- end
13
-
14
- class << Stellar::Transaction
15
- alias manage_offer manage_sell_offer
16
- alias create_passive_offer create_passive_sell_offer
2
+ alias_method :manage_offer, :manage_sell_offer
3
+ alias_method :create_passive_offer, :create_passive_sell_offer
17
4
 
18
5
  deprecate deprecator: Stellar::Deprecation,
19
6
  manage_offer: :manage_sell_offer,
@@ -32,9 +32,8 @@ module Stellar::Concerns
32
32
  #
33
33
  # @return [Array<Operation>] the operations
34
34
  def to_operations
35
- # FIXME: what was the purpose of this?
36
- # cloned = Marshal.load Marshal.dump(operations)
37
- operations.each do |op|
35
+ cloned = Marshal.load Marshal.dump(operations)
36
+ cloned.each do |op|
38
37
  op.source_account ||= source_account
39
38
  end
40
39
  end
@@ -0,0 +1,89 @@
1
+ module Stellar
2
+ module DSL
3
+ module_function
4
+
5
+ # Constructs a new ClaimPredicate using DSL
6
+ #
7
+ # @example fulfilled during [T+5min, T+60min] period, where T refers to claimable balance entry creation time
8
+ # Stellar::ClaimPredicate { before_relative_time(1.hour) & ~before_relative_time(5.minutes) }
9
+ #
10
+ # @example not fulfilled starting from today midnight until tomorrow midnight,
11
+ # Stellar::ClaimPredicate { before_absolute_time(Date.today.end_of_day) | ~before_absolute_time(Date.tomorrow.end_of_day) }
12
+ #
13
+ # @example always fulfilled
14
+ # Stellar::ClaimPredicate { }
15
+ def ClaimPredicate(&block)
16
+ return ClaimPredicate.unconditional unless block
17
+ ClaimPredicate.compose(&block)
18
+ end
19
+
20
+ def Claimant(destination, &block)
21
+ Claimant.new(
22
+ ClaimantType.claimant_type_v0,
23
+ Claimant::V0.new(
24
+ destination: KeyPair(destination).account_id,
25
+ predicate: ClaimPredicate(&block)
26
+ )
27
+ )
28
+ end
29
+
30
+ def Asset(subject = nil)
31
+ case subject
32
+ when Asset
33
+ subject
34
+ when nil, /^(XLM[-:])?native$/
35
+ Asset.native
36
+ when /^([0-9A-Z]{1,4})[-:](G[A-Z0-9]{55})$/
37
+ Asset.alphanum4($1, KeyPair($2))
38
+ when /^([0-9A-Z]{5,12})[-:](G[A-Z0-9]{55})$/
39
+ Asset.alphanum12($1, KeyPair($2))
40
+ else
41
+ raise TypeError, "Cannot convert #{subject.inspect} to Stellar::Asset"
42
+ end
43
+ end
44
+
45
+ # Generates Stellar::Keypair from subject, use Stellar::Client.to_keypair as shortcut.
46
+ # @param subject [String|Stellar::Account|Stellar::PublicKey|Stellar::SignerKey|Stellar::Keypair] subject.
47
+ # @return [Stellar::Keypair] Stellar::Keypair instance.
48
+ def KeyPair(subject = nil)
49
+ case subject
50
+ when ->(subj) { subj.respond_to?(:to_keypair) }
51
+ subject.to_keypair
52
+ when PublicKey
53
+ KeyPair.from_public_key(subject.value)
54
+ when SignerKey
55
+ KeyPair.from_raw_seed(subject.value)
56
+ when /^G[A-Z0-9]{55}$/
57
+ KeyPair.from_address(subject.to_str)
58
+ when /^S[A-Z0-9]{55}$/
59
+ KeyPair.from_seed(subject.to_str)
60
+ when /^.{32}$/
61
+ KeyPair.from_raw_seed(subject.to_str)
62
+ when nil
63
+ KeyPair.random
64
+ else
65
+ raise TypeError, "cannot convert #{subject.inspect} to Stellar::KeyPair"
66
+ end
67
+ end
68
+
69
+ # Provides conversion from different input types into the SignerKey to use in ManageData operation.
70
+ # @param input [String|zStellar::Account|Stellar::PublicKey|Stellar::SignerKey|Stellar::Keypair] subject.
71
+ # @return [Stellar::SignerKey] Stellar::Keypair instance.
72
+ def SignerKey(input = nil)
73
+ case input
74
+ when Transaction
75
+ SignerKey.pre_auth_tx(input.hash)
76
+ when /^[0-9A-Za-z+\/=]{44}$/
77
+ SignerKey.hash_x(Stellar::Convert.from_base64(input))
78
+ when /^[0-9a-f]{64}$/
79
+ SignerKey.hash_x(Stellar::Convert.from_hex(input))
80
+ when /^.{32}$/
81
+ SignerKey.hash_x(input)
82
+ else
83
+ SignerKey.ed25519(KeyPair(input))
84
+ end
85
+ end
86
+ end
87
+
88
+ include DSL
89
+ end
@@ -0,0 +1,50 @@
1
+ require "active_support/core_ext/string/inflections"
2
+ require "xdr"
3
+
4
+ # For every member of XDR::Enum define constant on the corresponding enum type class.
5
+ # Constant name is a member name stripped of the common prefix with enum type name.
6
+ XDR::DSL::Enum.redefine_method(:seal) do
7
+ names = [members.keys.first, name.demodulize.underscore + "_"].join(" ")
8
+ common_prefix = /\A(.*_).* \1.*\Z/.match(names)&.values_at(1)&.first
9
+ members.each do |name, value|
10
+ unless common_prefix.nil?
11
+ full_name, name = [name, name.delete_prefix(common_prefix)]
12
+ singleton_class.alias_method(name, full_name)
13
+ end
14
+ const_set(name.upcase, value)
15
+ end
16
+ self.sealed = true
17
+ end
18
+
19
+ XDR::DSL::Union.redefine_method(:switch) do |switch, arm = nil|
20
+ raise ArgumentError, "`switch_on` not defined yet" if switch_type.nil?
21
+
22
+ switch = normalize_switch_declaration(switch)
23
+ self.switches = switches.merge(switch => arm)
24
+
25
+ unless arm.nil?
26
+ define_singleton_method(arm) do |*args, **kwargs|
27
+ value_type = arms[arm]
28
+ value = if value_type.valid?(args.first)
29
+ args.first
30
+ elsif value_type.ancestors.include?(XDR::Struct)
31
+ value_type.new(kwargs)
32
+ elsif value_type.ancestors.include?(XDR::Union)
33
+ value_type.new(*args[0..1])
34
+ else
35
+ args.first
36
+ end
37
+ new(switch, value)
38
+ end
39
+ end
40
+ end
41
+
42
+ # XDR::Union delegates missing methods to the underlying value
43
+ XDR::Union.define_method(:method_missing) do |name, *args|
44
+ return super(name, *args) unless value&.respond_to?(name)
45
+ value&.public_send(name, *args)
46
+ end
47
+
48
+ XDR::Union.define_method(:respond_to_missing?) do |*args|
49
+ value&.respond_to?(*args)
50
+ end
@@ -1,44 +1,58 @@
1
1
  module Stellar
2
2
  class KeyPair
3
- def self.from_seed(seed)
4
- seed_bytes = Util::StrKey.check_decode(:seed, seed)
5
- from_raw_seed seed_bytes
6
- end
7
-
8
- def self.from_raw_seed(seed_bytes)
9
- secret_key = RbNaCl::SigningKey.new(seed_bytes)
10
- public_key = secret_key.verify_key
11
- new(public_key, secret_key)
12
- end
13
-
14
- def self.from_public_key(pk_bytes)
15
- public_key = RbNaCl::VerifyKey.new(pk_bytes)
16
- new(public_key)
17
- end
18
-
19
- def self.from_address(address)
20
- pk_bytes = Util::StrKey.check_decode(:account_id, address)
21
- from_public_key(pk_bytes)
22
- end
23
-
24
- def self.random
25
- secret_key = RbNaCl::SigningKey.generate
26
- public_key = secret_key.verify_key
27
- new(public_key, secret_key)
28
- end
29
-
30
- def self.from_network_passphrase(passphrase)
31
- network_id = Digest::SHA256.digest(passphrase)
32
- from_raw_seed network_id
3
+ module FactoryMethods
4
+ def from_seed(seed)
5
+ seed_bytes = Util::StrKey.check_decode(:seed, seed)
6
+ from_raw_seed seed_bytes
7
+ end
8
+
9
+ def from_address(address)
10
+ pk_bytes = Util::StrKey.check_decode(:account_id, address)
11
+ from_public_key(pk_bytes)
12
+ end
13
+
14
+ def from_raw_seed(seed_bytes)
15
+ secret_key = RbNaCl::SigningKey.new(seed_bytes)
16
+ public_key = secret_key.verify_key
17
+ new(public_key, secret_key)
18
+ end
19
+
20
+ def from_public_key(pk_bytes)
21
+ public_key = RbNaCl::VerifyKey.new(pk_bytes)
22
+ new(public_key)
23
+ end
24
+
25
+ def random
26
+ secret_key = RbNaCl::SigningKey.generate
27
+ public_key = secret_key.verify_key
28
+ new(public_key, secret_key)
29
+ end
30
+
31
+ def from_network_passphrase(passphrase)
32
+ network_id = Digest::SHA256.digest(passphrase)
33
+ from_raw_seed network_id
34
+ end
35
+
36
+ def master
37
+ from_raw_seed(Stellar.current_network_id)
38
+ end
39
+ end
40
+
41
+ extend FactoryMethods
42
+
43
+ # @param [RbNaCl::VerifyKey] public_key
44
+ # @param [RbNaCl::SigningKey, nil] secret_key
45
+ def initialize(public_key, secret_key = nil)
46
+ @public_key = public_key
47
+ @secret_key = secret_key
33
48
  end
34
49
 
35
- def self.master
36
- from_raw_seed(Stellar.current_network_id)
50
+ def address
51
+ Util::StrKey.check_encode(:account_id, raw_public_key)
37
52
  end
38
53
 
39
- def initialize(public_key, secret_key = nil)
40
- @public_key = public_key
41
- @secret_key = secret_key
54
+ def seed
55
+ Util::StrKey.check_encode(:seed, raw_seed)
42
56
  end
43
57
 
44
58
  def account_id
@@ -57,16 +71,17 @@ module Stellar
57
71
  Stellar::SignerKey.new :signer_key_type_ed25519, raw_public_key
58
72
  end
59
73
 
60
- def raw_public_key
61
- @public_key.to_bytes
62
- end
63
-
64
74
  def signature_hint
65
75
  # take last 4 bytes
66
76
  account_id.to_xdr.slice(-4, 4)
67
77
  end
68
78
 
79
+ def raw_public_key
80
+ @public_key.to_bytes
81
+ end
82
+
69
83
  def raw_seed
84
+ raise "no private key" if @secret_key.nil?
70
85
  @secret_key.to_bytes
71
86
  end
72
87
 
@@ -78,25 +93,13 @@ module Stellar
78
93
  @public_key
79
94
  end
80
95
 
81
- def address
82
- pk_bytes = raw_public_key
83
- Util::StrKey.check_encode(:account_id, pk_bytes)
84
- end
85
-
86
- def seed
87
- raise "no private key" if @secret_key.nil?
88
- # TODO: improve the error class above
89
- seed_bytes = raw_seed
90
- Util::StrKey.check_encode(:seed, seed_bytes)
91
- end
92
-
93
96
  def sign?
94
97
  !@secret_key.nil?
95
98
  end
96
99
 
97
100
  def sign(message)
98
- raise "no private key" if @secret_key.nil?
99
- # TODO: improve the error class above
101
+ raise NotImplementedError, "no private key, signing is not available" unless sign?
102
+
100
103
  @secret_key.sign(message)
101
104
  end
102
105
 
@@ -115,5 +118,9 @@ module Stellar
115
118
  rescue RbNaCl::BadSignatureError
116
119
  false
117
120
  end
121
+
122
+ def to_keypair
123
+ self
124
+ end
118
125
  end
119
126
  end