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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +114 -1
- data/README.md +4 -7
- data/generated/stellar-base-generated.rb +29 -1
- data/generated/stellar/account_entry.rb +3 -13
- data/generated/stellar/account_entry/ext.rb +2 -16
- data/generated/stellar/account_entry_extension_v1.rb +32 -0
- data/generated/stellar/account_entry_extension_v1/ext.rb +28 -0
- data/generated/stellar/account_entry_extension_v2.rb +34 -0
- data/generated/stellar/{account_entry/ext/v1 → account_entry_extension_v2}/ext.rb +8 -12
- data/generated/stellar/account_merge_result_code.rb +3 -1
- data/generated/stellar/begin_sponsoring_future_reserves_op.rb +18 -0
- data/generated/stellar/begin_sponsoring_future_reserves_result.rb +25 -0
- data/generated/stellar/begin_sponsoring_future_reserves_result_code.rb +29 -0
- data/generated/stellar/claim_claimable_balance_op.rb +18 -0
- data/generated/stellar/claim_claimable_balance_result.rb +25 -0
- data/generated/stellar/claim_claimable_balance_result_code.rb +31 -0
- data/generated/stellar/claim_predicate.rb +43 -0
- data/generated/stellar/claim_predicate_type.rb +30 -0
- data/generated/stellar/claimable_balance_entry.rb +44 -0
- data/generated/stellar/claimable_balance_entry/ext.rb +24 -0
- data/generated/stellar/claimable_balance_id.rb +23 -0
- data/generated/stellar/claimable_balance_id_type.rb +20 -0
- data/generated/stellar/claimant.rb +31 -0
- data/generated/stellar/claimant/v0.rb +22 -0
- data/generated/stellar/claimant_type.rb +20 -0
- data/generated/stellar/create_claimable_balance_op.rb +22 -0
- data/generated/stellar/create_claimable_balance_result.rb +27 -0
- data/generated/stellar/create_claimable_balance_result_code.rb +30 -0
- data/generated/stellar/end_sponsoring_future_reserves_result.rb +25 -0
- data/generated/stellar/end_sponsoring_future_reserves_result_code.rb +25 -0
- data/generated/stellar/envelope_type.rb +3 -1
- data/generated/stellar/inner_transaction_result.rb +2 -1
- data/generated/stellar/inner_transaction_result/result.rb +3 -1
- data/generated/stellar/ledger_entry.rb +4 -0
- data/generated/stellar/ledger_entry/data.rb +12 -8
- data/generated/stellar/ledger_entry/ext.rb +4 -0
- data/generated/stellar/ledger_entry_extension_v1.rb +30 -0
- data/generated/stellar/ledger_entry_extension_v1/ext.rb +24 -0
- data/generated/stellar/ledger_entry_type.rb +7 -5
- data/generated/stellar/ledger_key.rb +17 -8
- data/generated/stellar/ledger_key/claimable_balance.rb +20 -0
- data/generated/stellar/operation.rb +10 -0
- data/generated/stellar/operation/body.rb +45 -26
- data/generated/stellar/operation_id.rb +32 -0
- data/generated/stellar/operation_id/id.rb +24 -0
- data/generated/stellar/operation_result.rb +10 -0
- data/generated/stellar/operation_result/tr.rb +48 -28
- data/generated/stellar/operation_result_code.rb +3 -1
- data/generated/stellar/operation_type.rb +25 -15
- data/generated/stellar/path_payment_strict_receive_result.rb +2 -1
- data/generated/stellar/revoke_sponsorship_op.rb +36 -0
- data/generated/stellar/revoke_sponsorship_op/signer.rb +22 -0
- data/generated/stellar/revoke_sponsorship_result.rb +25 -0
- data/generated/stellar/revoke_sponsorship_result_code.rb +31 -0
- data/generated/stellar/revoke_sponsorship_type.rb +22 -0
- data/generated/stellar/transaction_result_code.rb +4 -2
- data/lib/stellar-base.rb +18 -5
- data/lib/stellar/account_flags.rb +1 -1
- data/lib/stellar/asset.rb +10 -0
- data/lib/stellar/{version.rb → base/version.rb} +1 -1
- data/lib/stellar/claim_predicate.rb +198 -0
- data/lib/stellar/compat.rb +2 -15
- data/lib/stellar/concerns/transaction.rb +2 -3
- data/lib/stellar/dsl.rb +89 -0
- data/lib/stellar/ext/xdr.rb +50 -0
- data/lib/stellar/key_pair.rb +60 -53
- data/lib/stellar/ledger_key.rb +32 -0
- data/lib/stellar/muxed_account.rb +16 -0
- data/lib/stellar/networks.rb +12 -12
- data/lib/stellar/operation.rb +59 -1
- data/lib/stellar/price.rb +11 -2
- data/lib/stellar/transaction.rb +17 -167
- data/lib/stellar/transaction_builder.rb +35 -18
- data/lib/stellar/transaction_envelope.rb +7 -43
- data/lib/stellar/transaction_v0.rb +5 -1
- data/lib/stellar/util/strkey.rb +6 -6
- metadata +162 -30
- data/generated/stellar/account_entry/ext/v1.rb +0 -34
- 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
|
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})
|
@@ -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
|
data/lib/stellar/compat.rb
CHANGED
@@ -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
|
-
|
7
|
-
|
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
|
-
|
36
|
-
|
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
|
data/lib/stellar/dsl.rb
ADDED
@@ -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
|
data/lib/stellar/key_pair.rb
CHANGED
@@ -1,44 +1,58 @@
|
|
1
1
|
module Stellar
|
2
2
|
class KeyPair
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
36
|
-
|
50
|
+
def address
|
51
|
+
Util::StrKey.check_encode(:account_id, raw_public_key)
|
37
52
|
end
|
38
53
|
|
39
|
-
def
|
40
|
-
|
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"
|
99
|
-
|
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
|