auction-ruby-base 0.1.1
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 +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +15 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +58 -0
- data/CONTRIBUTING.md +48 -0
- data/Gemfile +15 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +202 -0
- data/README.md +83 -0
- data/Rakefile +4 -0
- data/auction-ruby-base.gemspec +35 -0
- data/examples/create_account.rb +26 -0
- data/examples/low_level_transaction_post.rb +46 -0
- data/examples/mid_level_transaction_post.rb +33 -0
- data/examples/non_native_payment.rb +60 -0
- data/examples/offer.rb +75 -0
- data/examples/transaction_merge.rb +23 -0
- data/generated/stellar-base-generated.rb +174 -0
- data/generated/stellar/account_entry.rb +55 -0
- data/generated/stellar/account_entry/ext.rb +24 -0
- data/generated/stellar/account_flags.rb +31 -0
- data/generated/stellar/account_merge_result.rb +26 -0
- data/generated/stellar/account_merge_result_code.rb +30 -0
- data/generated/stellar/affirm_fail_op.rb +22 -0
- data/generated/stellar/affirm_fail_result.rb +25 -0
- data/generated/stellar/affirm_fail_result_code.rb +22 -0
- data/generated/stellar/affirm_pass_op.rb +24 -0
- data/generated/stellar/affirm_pass_result.rb +25 -0
- data/generated/stellar/affirm_pass_result_code.rb +22 -0
- data/generated/stellar/allow_trust_op.rb +38 -0
- data/generated/stellar/allow_trust_op/asset.rb +33 -0
- data/generated/stellar/allow_trust_result.rb +25 -0
- data/generated/stellar/allow_trust_result_code.rb +31 -0
- data/generated/stellar/asset.rb +47 -0
- data/generated/stellar/asset/alpha_num12.rb +22 -0
- data/generated/stellar/asset/alpha_num4.rb +22 -0
- data/generated/stellar/asset_type.rb +24 -0
- data/generated/stellar/auth.rb +20 -0
- data/generated/stellar/auth_cert.rb +22 -0
- data/generated/stellar/authenticated_message.rb +32 -0
- data/generated/stellar/authenticated_message/v0.rb +24 -0
- data/generated/stellar/bucket_entry.rb +28 -0
- data/generated/stellar/bucket_entry_type.rb +22 -0
- data/generated/stellar/change_trust_op.rb +22 -0
- data/generated/stellar/change_trust_result.rb +25 -0
- data/generated/stellar/change_trust_result_code.rb +31 -0
- data/generated/stellar/claim_offer_atom.rb +33 -0
- data/generated/stellar/create_account_op.rb +20 -0
- data/generated/stellar/create_account_result.rb +25 -0
- data/generated/stellar/create_account_result_code.rb +32 -0
- data/generated/stellar/create_bid_op.rb +20 -0
- data/generated/stellar/create_bid_result.rb +25 -0
- data/generated/stellar/create_bid_result_code.rb +22 -0
- data/generated/stellar/create_lot_op.rb +46 -0
- data/generated/stellar/create_lot_result.rb +25 -0
- data/generated/stellar/create_lot_result_code.rb +22 -0
- data/generated/stellar/create_passive_offer_op.rb +24 -0
- data/generated/stellar/crypto_key_type.rb +20 -0
- data/generated/stellar/curve25519_public.rb +18 -0
- data/generated/stellar/curve25519_secret.rb +18 -0
- data/generated/stellar/decorated_signature.rb +20 -0
- data/generated/stellar/dont_have.rb +20 -0
- data/generated/stellar/envelope_type.rb +24 -0
- data/generated/stellar/error.rb +20 -0
- data/generated/stellar/error_code.rb +28 -0
- data/generated/stellar/hello.rb +34 -0
- data/generated/stellar/hmac_sha256_key.rb +18 -0
- data/generated/stellar/hmac_sha256_mac.rb +18 -0
- data/generated/stellar/inflation_payout.rb +20 -0
- data/generated/stellar/inflation_result.rb +26 -0
- data/generated/stellar/inflation_result_code.rb +24 -0
- data/generated/stellar/ip_addr_type.rb +22 -0
- data/generated/stellar/ledger_entry.rb +52 -0
- data/generated/stellar/ledger_entry/data.rb +49 -0
- data/generated/stellar/ledger_entry/ext.rb +24 -0
- data/generated/stellar/ledger_entry_change.rb +35 -0
- data/generated/stellar/ledger_entry_change_type.rb +26 -0
- data/generated/stellar/ledger_entry_type.rb +32 -0
- data/generated/stellar/ledger_header.rb +69 -0
- data/generated/stellar/ledger_header/ext.rb +24 -0
- data/generated/stellar/ledger_header_history_entry.rb +33 -0
- data/generated/stellar/ledger_header_history_entry/ext.rb +24 -0
- data/generated/stellar/ledger_key.rb +87 -0
- data/generated/stellar/ledger_key/account.rb +20 -0
- data/generated/stellar/ledger_key/lot.rb +22 -0
- data/generated/stellar/ledger_key/message.rb +22 -0
- data/generated/stellar/ledger_key/offer.rb +22 -0
- data/generated/stellar/ledger_key/participant.rb +22 -0
- data/generated/stellar/ledger_key/proof.rb +22 -0
- data/generated/stellar/ledger_key/trust_line.rb +22 -0
- data/generated/stellar/ledger_scp_messages.rb +20 -0
- data/generated/stellar/ledger_upgrade.rb +31 -0
- data/generated/stellar/ledger_upgrade_type.rb +24 -0
- data/generated/stellar/lot_branch.rb +21 -0
- data/generated/stellar/lot_entry.rb +64 -0
- data/generated/stellar/lot_entry/ext.rb +24 -0
- data/generated/stellar/lot_type.rb +21 -0
- data/generated/stellar/manage_offer_effect.rb +24 -0
- data/generated/stellar/manage_offer_op.rb +28 -0
- data/generated/stellar/manage_offer_result.rb +26 -0
- data/generated/stellar/manage_offer_result_code.rb +50 -0
- data/generated/stellar/manage_offer_success_result.rb +34 -0
- data/generated/stellar/manage_offer_success_result/offer.rb +30 -0
- data/generated/stellar/memo.rb +38 -0
- data/generated/stellar/memo_type.rb +28 -0
- data/generated/stellar/message_entry.rb +38 -0
- data/generated/stellar/message_entry/ext.rb +24 -0
- data/generated/stellar/message_type.rb +51 -0
- data/generated/stellar/offer_entry.rb +49 -0
- data/generated/stellar/offer_entry/ext.rb +24 -0
- data/generated/stellar/offer_entry_flags.rb +21 -0
- data/generated/stellar/operation.rb +65 -0
- data/generated/stellar/operation/body.rb +88 -0
- data/generated/stellar/operation_meta.rb +18 -0
- data/generated/stellar/operation_result.rb +67 -0
- data/generated/stellar/operation_result/tr.rb +89 -0
- data/generated/stellar/operation_result_code.rb +25 -0
- data/generated/stellar/operation_type.rb +52 -0
- data/generated/stellar/participant_entry.rb +39 -0
- data/generated/stellar/participant_entry/ext.rb +24 -0
- data/generated/stellar/participant_state.rb +25 -0
- data/generated/stellar/path_payment_op.rb +32 -0
- data/generated/stellar/path_payment_result.rb +38 -0
- data/generated/stellar/path_payment_result/success.rb +22 -0
- data/generated/stellar/path_payment_result_code.rb +47 -0
- data/generated/stellar/payment_op.rb +22 -0
- data/generated/stellar/payment_result.rb +25 -0
- data/generated/stellar/payment_result_code.rb +41 -0
- data/generated/stellar/peer_address.rb +33 -0
- data/generated/stellar/peer_address/ip.rb +29 -0
- data/generated/stellar/price.rb +20 -0
- data/generated/stellar/proof_entry.rb +42 -0
- data/generated/stellar/proof_entry/ext.rb +24 -0
- data/generated/stellar/provide_proof_op.rb +24 -0
- data/generated/stellar/provide_proof_result.rb +25 -0
- data/generated/stellar/provide_proof_result_code.rb +22 -0
- data/generated/stellar/public_key.rb +23 -0
- data/generated/stellar/register_participant_op.rb +22 -0
- data/generated/stellar/register_participant_result.rb +25 -0
- data/generated/stellar/register_participant_result_code.rb +22 -0
- data/generated/stellar/scp_ballot.rb +20 -0
- data/generated/stellar/scp_envelope.rb +20 -0
- data/generated/stellar/scp_history_entry.rb +23 -0
- data/generated/stellar/scp_history_entry_v0.rb +20 -0
- data/generated/stellar/scp_nomination.rb +22 -0
- data/generated/stellar/scp_quorum_set.rb +22 -0
- data/generated/stellar/scp_statement.rb +58 -0
- data/generated/stellar/scp_statement/pledges.rb +63 -0
- data/generated/stellar/scp_statement/pledges/confirm.rb +30 -0
- data/generated/stellar/scp_statement/pledges/externalize.rb +26 -0
- data/generated/stellar/scp_statement/pledges/prepare.rb +32 -0
- data/generated/stellar/scp_statement_type.rb +26 -0
- data/generated/stellar/send_message_op.rb +22 -0
- data/generated/stellar/send_message_result.rb +25 -0
- data/generated/stellar/send_message_result_code.rb +22 -0
- data/generated/stellar/set_options_op.rb +41 -0
- data/generated/stellar/set_options_result.rb +25 -0
- data/generated/stellar/set_options_result_code.rb +40 -0
- data/generated/stellar/signer.rb +20 -0
- data/generated/stellar/simple_payment_result.rb +22 -0
- data/generated/stellar/stellar_message.rb +74 -0
- data/generated/stellar/stellar_value.rb +41 -0
- data/generated/stellar/stellar_value/ext.rb +24 -0
- data/generated/stellar/threshold_indexes.rb +26 -0
- data/generated/stellar/time_bounds.rb +20 -0
- data/generated/stellar/transaction.rb +50 -0
- data/generated/stellar/transaction/ext.rb +24 -0
- data/generated/stellar/transaction_envelope.rb +20 -0
- data/generated/stellar/transaction_history_entry.rb +33 -0
- data/generated/stellar/transaction_history_entry/ext.rb +24 -0
- data/generated/stellar/transaction_history_result_entry.rb +33 -0
- data/generated/stellar/transaction_history_result_entry/ext.rb +24 -0
- data/generated/stellar/transaction_meta.rb +23 -0
- data/generated/stellar/transaction_result.rb +43 -0
- data/generated/stellar/transaction_result/ext.rb +24 -0
- data/generated/stellar/transaction_result/result.rb +30 -0
- data/generated/stellar/transaction_result_code.rb +45 -0
- data/generated/stellar/transaction_result_pair.rb +20 -0
- data/generated/stellar/transaction_result_set.rb +18 -0
- data/generated/stellar/transaction_set.rb +20 -0
- data/generated/stellar/trust_line_entry.rb +41 -0
- data/generated/stellar/trust_line_entry/ext.rb +24 -0
- data/generated/stellar/trust_line_flags.rb +21 -0
- data/lib/stellar-base.rb +33 -0
- data/lib/stellar/account_flags.rb +28 -0
- data/lib/stellar/asset.rb +69 -0
- data/lib/stellar/base.rb +1 -0
- data/lib/stellar/base/version.rb +5 -0
- data/lib/stellar/convert.rb +32 -0
- data/lib/stellar/key_pair.rb +112 -0
- data/lib/stellar/networks.rb +45 -0
- data/lib/stellar/operation.rb +384 -0
- data/lib/stellar/path_payment_result.rb +17 -0
- data/lib/stellar/price.rb +32 -0
- data/lib/stellar/thresholds.rb +39 -0
- data/lib/stellar/transaction.rb +205 -0
- data/lib/stellar/transaction_envelope.rb +32 -0
- data/lib/stellar/util/continued_fraction.rb +96 -0
- data/lib/stellar/util/strkey.rb +43 -0
- data/spec/lib/stellar/account_flags_spec.rb +19 -0
- data/spec/lib/stellar/asset_spec.rb +45 -0
- data/spec/lib/stellar/convert_spec.rb +61 -0
- data/spec/lib/stellar/key_pair_spec.rb +238 -0
- data/spec/lib/stellar/networks_spec.rb +77 -0
- data/spec/lib/stellar/operation_spec.rb +13 -0
- data/spec/lib/stellar/path_payment_result_spec.rb +95 -0
- data/spec/lib/stellar/price_spec.rb +34 -0
- data/spec/lib/stellar/thresholds_spec.rb +62 -0
- data/spec/lib/stellar/transaction_envelope_spec.rb +93 -0
- data/spec/lib/stellar/transaction_spec.rb +83 -0
- data/spec/lib/stellar/util/strkey_spec.rb +46 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/matchers/be_strkey.rb +9 -0
- data/spec/support/matchers/eq_bytes.rb +5 -0
- data/spec/support/matchers/have_length.rb +5 -0
- data/tasks/rspec.rake +6 -0
- data/tasks/travis.rake +1 -0
- data/tasks/xdr.rake +50 -0
- data/xdr/Stellar-SCP.x +86 -0
- data/xdr/Stellar-ledger-entries.x +351 -0
- data/xdr/Stellar-ledger.x +288 -0
- data/xdr/Stellar-overlay.x +146 -0
- data/xdr/Stellar-transaction.x +936 -0
- data/xdr/Stellar-types.x +55 -0
- metadata +495 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
class << Thresholds
|
|
3
|
+
COMPONENTS = [:master_weight, :low, :medium, :high]
|
|
4
|
+
VALID_RANGE = 0..255
|
|
5
|
+
|
|
6
|
+
def make(thresholds={})
|
|
7
|
+
|
|
8
|
+
# error if any of the needed components are not provided
|
|
9
|
+
if COMPONENTS.any?{|c| thresholds[c].blank? }
|
|
10
|
+
raise ArgumentError, "invalid thresholds hash, must have #{COMPONENTS.inspect} keys, had: #{thresholds.keys.inspect}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# error if any of the needed components are not numbers 0 <= N <= 255
|
|
14
|
+
COMPONENTS.each do |c|
|
|
15
|
+
good = true
|
|
16
|
+
|
|
17
|
+
good &&= thresholds[c].is_a?(Fixnum)
|
|
18
|
+
good &&= VALID_RANGE.include? thresholds[c]
|
|
19
|
+
|
|
20
|
+
unless good
|
|
21
|
+
raise ArgumentError, "invalid #{c.inspect}, must be number in (0..255), got #{thresholds[c].inspect}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
thresholds.values_at(*COMPONENTS).pack("C*")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def parse(combined)
|
|
30
|
+
master_weight, low, medium, high = combined.unpack("C*")
|
|
31
|
+
{
|
|
32
|
+
master_weight: master_weight,
|
|
33
|
+
low: low,
|
|
34
|
+
medium: medium,
|
|
35
|
+
high: high,
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
class Transaction
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# @see Stellar::Operation.payment
|
|
6
|
+
def self.payment(attributes={})
|
|
7
|
+
make :payment, attributes
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# @see Stellar::Operation.path_payment
|
|
12
|
+
def self.path_payment(attributes={})
|
|
13
|
+
make :path_payment, attributes
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# @see Stellar::Operation.create_account
|
|
18
|
+
def self.create_account(attributes={})
|
|
19
|
+
make :create_account, attributes
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# @see Stellar::Operation.create_account
|
|
24
|
+
def self.provide_proof(attributes={})
|
|
25
|
+
make :provide_proof, attributes
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# @see Stellar::Operation.create_lot
|
|
30
|
+
def self.create_lot(attributes={})
|
|
31
|
+
make :create_lot, attributes
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.register_participant(attributes={})
|
|
35
|
+
make :register_participant, attributes
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# @see Stellar::Operation.change_trust
|
|
40
|
+
def self.change_trust(attributes={})
|
|
41
|
+
make :change_trust, attributes
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# @see Stellar::Operation.create_offer
|
|
46
|
+
def self.manage_offer(attributes={})
|
|
47
|
+
make :manage_offer, attributes
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# @see Stellar::Operation.create_passive_offer
|
|
52
|
+
def self.create_passive_offer(attributes={})
|
|
53
|
+
make :create_passive_offer, attributes
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#
|
|
57
|
+
# @see Stellar::Operation.set_options
|
|
58
|
+
def self.set_options(attributes={})
|
|
59
|
+
make :set_options, attributes
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# @see Stellar::Operation.allow_trust
|
|
64
|
+
def self.allow_trust(attributes={})
|
|
65
|
+
make :allow_trust, attributes
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# @see Stellar::Operation.account_merge
|
|
70
|
+
def self.account_merge(attributes={})
|
|
71
|
+
make :account_merge, attributes
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# @see Stellar::Operation.inflation
|
|
76
|
+
def self.inflation(attributes={})
|
|
77
|
+
make :inflation, attributes
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Helper method to create a transaction with a single
|
|
82
|
+
# operation of the provided type. See class methods
|
|
83
|
+
# on Stellar::Operation for available values for
|
|
84
|
+
# operation_type.
|
|
85
|
+
#
|
|
86
|
+
# @see Stellar::Operation
|
|
87
|
+
#
|
|
88
|
+
# @param operation_type [Symbol] the operation to use
|
|
89
|
+
# @param attributes={} [Hash] attributes to use for both the transaction and the operation
|
|
90
|
+
#
|
|
91
|
+
# @return [Stellar::Transaction] the resulting transaction
|
|
92
|
+
def self.make(operation_type, attributes={})
|
|
93
|
+
for_account(attributes).tap do |result|
|
|
94
|
+
result.operations << Operation.send(operation_type, attributes)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Helper method to create the skeleton of a transaction.
|
|
101
|
+
# The resulting transaction will have its source account,
|
|
102
|
+
# sequence, fee, min ledger and max ledger set.
|
|
103
|
+
#
|
|
104
|
+
#
|
|
105
|
+
# @param attributes={} [type] [description]
|
|
106
|
+
#
|
|
107
|
+
# @return [Stellar::Transaction] the resulting skeleton
|
|
108
|
+
def self.for_account(attributes={})
|
|
109
|
+
account = attributes[:account]
|
|
110
|
+
sequence = attributes[:sequence]
|
|
111
|
+
fee = attributes[:fee]
|
|
112
|
+
|
|
113
|
+
raise ArgumentError, "Bad :account" unless account.is_a?(KeyPair)
|
|
114
|
+
raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
|
|
115
|
+
raise ArgumentError, "Bad :fee #{sequence}" if fee.present? && !fee.is_a?(Integer)
|
|
116
|
+
|
|
117
|
+
new.tap do |result|
|
|
118
|
+
result.seq_num = sequence
|
|
119
|
+
result.fee = fee
|
|
120
|
+
result.memo = make_memo(attributes[:memo])
|
|
121
|
+
result.source_account = account.account_id
|
|
122
|
+
result.apply_defaults
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def sign(key_pair)
|
|
127
|
+
key_pair.sign(hash)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def sign_decorated(key_pair)
|
|
131
|
+
key_pair.sign_decorated(hash)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def hash
|
|
135
|
+
Digest::SHA256.digest(signature_base)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Returns the string of bytes that, when hashed, provide the value which
|
|
139
|
+
# should be signed to create a valid stellar transaciton signature
|
|
140
|
+
def signature_base
|
|
141
|
+
signature_base_prefix + to_xdr
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def signature_base_prefix
|
|
145
|
+
val = Stellar::EnvelopeType.envelope_type_tx
|
|
146
|
+
|
|
147
|
+
Stellar.current_network_id + Stellar::EnvelopeType.to_xdr(val)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def to_envelope(*key_pairs)
|
|
151
|
+
signatures = key_pairs.map(&method(:sign_decorated))
|
|
152
|
+
TransactionEnvelope.new({
|
|
153
|
+
:signatures => signatures,
|
|
154
|
+
:tx => self
|
|
155
|
+
})
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def merge(other)
|
|
159
|
+
cloned = Marshal.load Marshal.dump(self)
|
|
160
|
+
cloned.operations += other.to_operations
|
|
161
|
+
cloned
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Extracts the operations from this single transaction,
|
|
167
|
+
# setting the source account on the extracted operations.
|
|
168
|
+
#
|
|
169
|
+
# Useful for merging transactions.
|
|
170
|
+
#
|
|
171
|
+
# @return [Array<Operation>] the operations
|
|
172
|
+
def to_operations
|
|
173
|
+
cloned = Marshal.load Marshal.dump(operations)
|
|
174
|
+
operations.each do |op|
|
|
175
|
+
op.source_account = self.source_account
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def apply_defaults
|
|
180
|
+
self.operations ||= []
|
|
181
|
+
self.fee ||= 100
|
|
182
|
+
self.memo ||= Memo.new(:memo_none)
|
|
183
|
+
self.ext ||= Stellar::Transaction::Ext.new 0
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
private
|
|
187
|
+
def self.make_memo(memo)
|
|
188
|
+
case memo
|
|
189
|
+
when Stellar::Memo ;
|
|
190
|
+
memo
|
|
191
|
+
when nil ;
|
|
192
|
+
nil
|
|
193
|
+
when Integer ;
|
|
194
|
+
Memo.new(:memo_id, memo)
|
|
195
|
+
when String ;
|
|
196
|
+
Memo.new(:memo_text, memo)
|
|
197
|
+
when Array ;
|
|
198
|
+
t, val = *memo
|
|
199
|
+
Memo.new(:"memo_#{t}", val)
|
|
200
|
+
else
|
|
201
|
+
raise ArgumentError, "Bad :memo"
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
class TransactionEnvelope
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# Checks to ensure that every signature for the envelope is
|
|
6
|
+
# a valid signature of one of the provided `key_pairs`
|
|
7
|
+
#
|
|
8
|
+
# NOTE: this does not do any authorization checks, which requires access to
|
|
9
|
+
# the current ledger state.
|
|
10
|
+
#
|
|
11
|
+
# @param *key_pairs [Array<Stellar::KeyPair>] The key pairs to check the envelopes signatures against
|
|
12
|
+
#
|
|
13
|
+
# @return [Boolean] true if all signatures are from the provided key_pairs and validly sign the tx's hash
|
|
14
|
+
def signed_correctly?(*key_pairs)
|
|
15
|
+
hash = tx.hash
|
|
16
|
+
return false if signatures.empty?
|
|
17
|
+
|
|
18
|
+
key_index = key_pairs.index_by(&:signature_hint)
|
|
19
|
+
|
|
20
|
+
signatures.all? do |sig|
|
|
21
|
+
key_pair = key_index[sig.hint]
|
|
22
|
+
break false if key_pair.nil?
|
|
23
|
+
|
|
24
|
+
key_pair.verify(sig.signature, hash)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def hash
|
|
29
|
+
Digest::SHA256.digest(to_xdr)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
module Util
|
|
3
|
+
class ContinuedFraction
|
|
4
|
+
MAX_PRECISION = (2**32) - 1
|
|
5
|
+
attr_reader :i
|
|
6
|
+
attr_reader :f
|
|
7
|
+
|
|
8
|
+
def self.best_r(number, max_precision=MAX_PRECISION)
|
|
9
|
+
cur_cf = new(number)
|
|
10
|
+
|
|
11
|
+
loop do
|
|
12
|
+
next_cf = cur_cf.extend()
|
|
13
|
+
cur_r = cur_cf.to_r(max_precision)
|
|
14
|
+
next_r = next_cf.to_r(max_precision)
|
|
15
|
+
|
|
16
|
+
break cur_r if cur_cf.done? || cur_r == next_r
|
|
17
|
+
|
|
18
|
+
cur_cf = next_cf
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
cur_cf.to_r(max_precision)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(val, parents=[])
|
|
25
|
+
@i = val.floor
|
|
26
|
+
@f = val - @i
|
|
27
|
+
@parents = parents
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_a
|
|
31
|
+
@parents + [i]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def error(actual)
|
|
35
|
+
(actual - to_f).abs
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_f
|
|
39
|
+
convergent = convergents.last
|
|
40
|
+
convergent.n / convergent.d.to_f
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def convergents
|
|
44
|
+
return @convergents if defined? @convergents
|
|
45
|
+
|
|
46
|
+
c = [Fraction.new(0,1), Fraction.new(1,0)]
|
|
47
|
+
to_a.each_with_index do |a, i|
|
|
48
|
+
i = i + 2
|
|
49
|
+
|
|
50
|
+
h = a * c[i-1].n + c[i-2].n
|
|
51
|
+
k = a * c[i-1].d + c[i-2].d
|
|
52
|
+
c << Fraction.new(h,k)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
@converegents = c[2..-1]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def to_r(max_precision=MAX_PRECISION)
|
|
59
|
+
fraction = convergents.take_while do |c|
|
|
60
|
+
c.n <= max_precision && c.d <= max_precision
|
|
61
|
+
end.last
|
|
62
|
+
|
|
63
|
+
Rational(fraction.n, fraction.d)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def done?
|
|
67
|
+
@f == 0
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def extend(count=1)
|
|
71
|
+
result = self
|
|
72
|
+
|
|
73
|
+
count.times do
|
|
74
|
+
break if result.done?
|
|
75
|
+
result = ContinuedFraction.new(1 / result.f, result.to_a)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
result
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class Fraction
|
|
82
|
+
attr_reader :n
|
|
83
|
+
attr_reader :d
|
|
84
|
+
|
|
85
|
+
def initialize(n,d)
|
|
86
|
+
@n = n
|
|
87
|
+
@d = d
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def to_r
|
|
91
|
+
Rational(@n, @d)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
module Util
|
|
3
|
+
|
|
4
|
+
require 'base32'
|
|
5
|
+
require 'digest/crc16_xmodem'
|
|
6
|
+
|
|
7
|
+
class StrKey
|
|
8
|
+
|
|
9
|
+
VERSION_BYTES = {
|
|
10
|
+
account_id: [ 6 << 3].pack("C"), # Base32-encodes to 'G...'
|
|
11
|
+
seed: [18 << 3].pack("C"), # Base32-encodes to 'S...'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
def self.check_encode(version, byte_str)
|
|
15
|
+
version_byte = VERSION_BYTES[version]
|
|
16
|
+
raise ArgumentError, "Invalid version: #{version}" if version_byte.blank?
|
|
17
|
+
payload = version_byte + byte_str.dup.force_encoding("BINARY")
|
|
18
|
+
check = checksum(payload)
|
|
19
|
+
Base32.encode(payload + check)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.check_decode(expected_version, str)
|
|
23
|
+
decoded = Base32.decode(str) rescue (raise ArgumentError, "Invalid base32 string")
|
|
24
|
+
version_byte = decoded[0]
|
|
25
|
+
payload = decoded[1...-2]
|
|
26
|
+
check = decoded[-2..-1]
|
|
27
|
+
version = VERSION_BYTES.key(version_byte)
|
|
28
|
+
|
|
29
|
+
raise ArgumentError, "Unexpected version: #{version.inspect}" if version != expected_version
|
|
30
|
+
raise ArgumentError, "Invalid checksum" if check != checksum(decoded[0...-2])
|
|
31
|
+
payload
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# return the "XModem CRC16" (CCITT-like, but with 0-init and MSB first)
|
|
35
|
+
# packed into a string in little-endian order
|
|
36
|
+
def self.checksum(bytes)
|
|
37
|
+
crc = Digest::CRC16XModem.checksum(bytes)
|
|
38
|
+
[crc].pack("S<")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Stellar::AccountFlags do
|
|
4
|
+
subject{ Stellar::AccountFlags }
|
|
5
|
+
let(:raw) { 3 }
|
|
6
|
+
let(:result) { subject.parse_mask raw }
|
|
7
|
+
|
|
8
|
+
it "parses correctly" do
|
|
9
|
+
expect(subject.parse_mask(1)).to eq([Stellar::AccountFlags.auth_required_flag])
|
|
10
|
+
expect(subject.parse_mask(2)).to eq([Stellar::AccountFlags.auth_revocable_flag])
|
|
11
|
+
expect(subject.parse_mask(3)).to eq([Stellar::AccountFlags.auth_required_flag, Stellar::AccountFlags.auth_revocable_flag])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "makes correctly" do
|
|
15
|
+
expect(subject.make_mask([Stellar::AccountFlags.auth_required_flag])).to eq(1)
|
|
16
|
+
expect(subject.make_mask([Stellar::AccountFlags.auth_revocable_flag])).to eq(2)
|
|
17
|
+
expect(subject.make_mask([Stellar::AccountFlags.auth_required_flag, Stellar::AccountFlags.auth_revocable_flag])).to eq(3)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Stellar::Asset, ".native" do
|
|
4
|
+
it "returns a asset instance whose type is 'AssetType.asset_type_native'" do
|
|
5
|
+
expect(Stellar::Asset.native.type).to eq(Stellar::AssetType.asset_type_native)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe Stellar::Asset, ".alphanum4" do
|
|
10
|
+
it "returns a asset instance whose type is 'AssetType.asset_type_credit_alphanum4'" do
|
|
11
|
+
result = Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master)
|
|
12
|
+
expect(result.type).to eq(Stellar::AssetType.asset_type_credit_alphanum4)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "pads the code to 4 bytes, padding on the right and with null bytes" do
|
|
16
|
+
result = Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master)
|
|
17
|
+
expect(result.code).to eq("USD\x00")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe Stellar::Asset, ".alphanum12" do
|
|
22
|
+
it "returns a asset instance whose type is 'AssetType.asset_type_credit_alphanum12'" do
|
|
23
|
+
result = Stellar::Asset.alphanum12("USD", Stellar::KeyPair.master)
|
|
24
|
+
expect(result.type).to eq(Stellar::AssetType.asset_type_credit_alphanum12)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "pads the code to 12 bytes, padding on the right and with null bytes" do
|
|
28
|
+
result = Stellar::Asset.alphanum12("USD", Stellar::KeyPair.master)
|
|
29
|
+
expect(result.code).to eq("USD\x00\x00\x00\x00\x00\x00\x00\x00\x00")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe Stellar::Asset, "#code" do
|
|
34
|
+
it "returns the asset_code for either alphanum4 or alphanum12 assets" do
|
|
35
|
+
a4 = Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master)
|
|
36
|
+
a12 = Stellar::Asset.alphanum12("USD", Stellar::KeyPair.master)
|
|
37
|
+
|
|
38
|
+
expect(a4.code.strip).to eq("USD")
|
|
39
|
+
expect(a12.code.strip).to eq("USD")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "raises an error when called on a native asset" do
|
|
43
|
+
expect{ Stellar::Asset.native.code }.to raise_error(RuntimeError)
|
|
44
|
+
end
|
|
45
|
+
end
|