steem-ruby 0.9.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c0d2e4cfae2885bc24acaa7d2a5f046e73a1505
4
- data.tar.gz: ddfdd7c5505ada6ea5e67584e51f6b5241e74bb6
3
+ metadata.gz: 0d2df68c704478da2f78e2cdee3a423523950f27
4
+ data.tar.gz: f8e6912e7b808be2bb7c065dfb177d0ef6a98a53
5
5
  SHA512:
6
- metadata.gz: ec9da3a5222a1ef5bf503ab496eeb12b88609ff1b76d0fd888ca10a355fa3bf0c1bea497a75327a5922a7b002d7b8f19d38eb9b047b431d5fa532eea740c3fa3
7
- data.tar.gz: 3a3aac4b912eeb02c92c97b9e74be3c747595b0acfffd75318258d4b89b99b1569776ff9aa4d7393aa0176b45b2170f5723195aafc87729ae7e22f9cb733d944
6
+ metadata.gz: 8b93714f563a05179fdbcf1c45af4e2279047343b86d1e932bb5ea306a8c7a508f8769b8a22a9415f4344effd591d0f5f86bcfc02a004bf34478fdd140a599ec
7
+ data.tar.gz: 12bf547182d8a9abae9d0182cb21f509e176c46f283b3683cebc7b57fc9efb6b3cdabf94538ba1b86550824e5483526257b13d45476d63bf7402bff5b393902e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- steem-ruby (0.9.0)
4
+ steem-ruby (0.9.1)
5
5
  bitcoin-ruby (~> 0.0, >= 0.0.18)
6
6
  ffi (~> 1.9, >= 1.9.23)
7
7
  hashie (~> 3.5, >= 3.5.7)
@@ -18,8 +18,8 @@ GEM
18
18
  coderay (1.1.2)
19
19
  crack (0.4.3)
20
20
  safe_yaml (~> 1.0.0)
21
- docile (1.3.0)
22
- ffi (1.9.23)
21
+ docile (1.3.1)
22
+ ffi (1.9.25)
23
23
  hashdiff (0.3.7)
24
24
  hashie (3.5.7)
25
25
  json (2.1.0)
@@ -28,8 +28,8 @@ GEM
28
28
  little-plugger (~> 1.1)
29
29
  multi_json (~> 1.10)
30
30
  method_source (0.9.0)
31
- minitest (5.10.3)
32
- minitest-line (0.6.4)
31
+ minitest (5.11.3)
32
+ minitest-line (0.6.5)
33
33
  minitest (~> 5.0)
34
34
  minitest-proveit (1.0.0)
35
35
  minitest (> 5, < 7)
@@ -46,11 +46,11 @@ GEM
46
46
  simplecov-html (~> 0.10.0)
47
47
  simplecov-html (0.10.2)
48
48
  vcr (4.0.0)
49
- webmock (3.3.0)
49
+ webmock (3.4.2)
50
50
  addressable (>= 2.3.6)
51
51
  crack (>= 0.3.2)
52
52
  hashdiff
53
- yard (0.9.12)
53
+ yard (0.9.14)
54
54
 
55
55
  PLATFORMS
56
56
  ruby
data/README.md CHANGED
@@ -13,7 +13,7 @@ Full documentation: http://www.rubydoc.info/gems/steem-ruby
13
13
 
14
14
  The `steem-ruby` gem was written from the ground up by `@inertia`, who is also the author of [`radiator`](https://github.com/inertia186/radiator).
15
15
 
16
- > "I intend to continue work on `radiator` indefinitely. But in `radiator-0.5`, I intend to refactor `radiator` so that is uses `steem-ruby` as its core. This means that some features of `radiator` like Serialization will become redundant. I think it's still useful for radiator to do its own serialzation because it reduces the number of API requests." - @inertia
16
+ > "I intend to continue work on `radiator` indefinitely. But in `radiator-0.5`, I intend to refactor `radiator` so that is uses `steem-ruby` as its core. This means that some features of `radiator` like Serialization will become redundant. I think it's still useful for radiator to do its own serialization because it reduces the number of API requests." - @inertia
17
17
 
18
18
  | `radiator` | `steem-ruby` |
19
19
  |-|-|
@@ -90,7 +90,7 @@ end
90
90
  In addition to signing with multiple `wif` private keys, it is possible to also export a partially signed transaction to have signing completed by someone else.
91
91
 
92
92
  ```ruby
93
- builder = TransactionBuilder.new(wif: wif1)
93
+ builder = Steem::TransactionBuilder.new(wif: wif1)
94
94
 
95
95
  builder.put(vote: {
96
96
  voter: voter,
@@ -110,8 +110,8 @@ Then send the contents of `trx.json` to the other signing party so they can priv
110
110
 
111
111
  ```ruby
112
112
  trx = open('trx.json').read
113
- builder = TransactionBuilder.new(wif: wif2, trx: trx)
114
- api = Steem::NetworkBroadcastApi.new
113
+ builder = Steem::TransactionBuilder.new(wif: wif2, trx: trx)
114
+ api = Steem::CondenserApi.new
115
115
  trx = builder.transaction
116
116
  api.broadcast_transaction_synchronous(trx: trx)
117
117
  ```
data/lib/steem/api.rb CHANGED
@@ -39,7 +39,7 @@ module Steem
39
39
  attr_accessor :chain, :methods
40
40
 
41
41
  # Use this for debugging naive thread handler.
42
- # DEFAULT_RPC_CLIENT_CLASS = RPC::BaseClient
42
+ # DEFAULT_RPC_CLIENT_CLASS = RPC::HttpClient
43
43
  DEFAULT_RPC_CLIENT_CLASS = RPC::ThreadSafeHttpClient
44
44
 
45
45
  def self.api_name=(api_name)
@@ -15,131 +15,148 @@ module Steem
15
15
 
16
16
  def self.build_error(error, context)
17
17
  if error.message == 'Unable to acquire database lock'
18
- raise Steem::RemoteDatabaseLockError, error.message, JSON.pretty_generate(error)
18
+ raise Steem::RemoteDatabaseLockError, error.message, build_backtrace(error)
19
19
  end
20
20
 
21
21
  if error.message.include? 'Internal Error'
22
- raise Steem::RemoteNodeError.new, error.message, JSON.pretty_generate(error)
22
+ raise Steem::RemoteNodeError.new, error.message, build_backtrace(error)
23
23
  end
24
24
 
25
25
  if error.message.include? 'plugin not enabled'
26
- raise Steem::PluginNotEnabledError, error.message, JSON.pretty_generate(error)
26
+ raise Steem::PluginNotEnabledError, error.message, build_backtrace(error)
27
27
  end
28
28
 
29
29
  if error.message.include? 'argument'
30
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
30
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
31
31
  end
32
32
 
33
33
  if error.message.start_with? 'Bad Cast:'
34
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
34
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
35
35
  end
36
36
 
37
37
  if error.message.include? 'prefix_len'
38
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
38
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
39
39
  end
40
40
 
41
41
  if error.message.include? 'Parse Error'
42
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
42
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
43
43
  end
44
44
 
45
45
  if error.message.include? 'unknown key'
46
- raise Steem::ArgumentError, "#{context}: #{error.message} (or content has been deleted)", JSON.pretty_generate(error)
46
+ raise Steem::ArgumentError, "#{context}: #{error.message} (or content has been deleted)", build_backtrace(error)
47
47
  end
48
48
 
49
49
  if error.message.include? 'Comment is not in account\'s comments'
50
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
50
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
51
51
  end
52
52
 
53
53
  if error.message.include? 'Could not find comment'
54
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
54
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
55
55
  end
56
56
 
57
57
  if error.message.include? 'unable to convert ISO-formatted string to fc::time_point_sec'
58
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
58
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
59
59
  end
60
60
 
61
61
  if error.message.include? 'Input data have to treated as object.'
62
- raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
62
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
63
+ end
64
+
65
+ if error.message.include? 'base.amount > share_type(0)'
66
+ raise Steem::ArgumentError, "#{context}: #{error.message}", build_backtrace(error)
63
67
  end
64
68
 
65
69
  if error.message.include? 'blk->transactions.size() > itr->trx_in_block'
66
- raise Steem::VirtualOperationsNotAllowedError, "#{context}: #{error.message}", JSON.pretty_generate(error)
70
+ raise Steem::VirtualOperationsNotAllowedError, "#{context}: #{error.message}", build_backtrace(error)
67
71
  end
68
72
 
69
73
  if error.message.include? 'A transaction must have at least one operation'
70
- raise Steem::EmptyTransactionError, "#{context}: #{error.message}", JSON.pretty_generate(error)
74
+ raise Steem::EmptyTransactionError, "#{context}: #{error.message}", build_backtrace(error)
71
75
  end
72
76
 
73
77
  if error.message.include? 'transaction expiration exception'
74
- raise Steem::TransactionExpiredError, "#{context}: #{error.message}", JSON.pretty_generate(error)
78
+ raise Steem::TransactionExpiredError, "#{context}: #{error.message}", build_backtrace(error)
75
79
  end
76
80
 
77
81
  if error.message.include? 'Duplicate transaction check failed'
78
- raise Steem::DuplicateTransactionError, "#{context}: #{error.message}", JSON.pretty_generate(error)
82
+ raise Steem::DuplicateTransactionError, "#{context}: #{error.message}", build_backtrace(error)
79
83
  end
80
84
 
81
85
  if error.message.include? 'signature is not canonical'
82
- raise Steem::NonCanonicalSignatureError, "#{context}: #{error.message}", JSON.pretty_generate(error)
86
+ raise Steem::NonCanonicalSignatureError, "#{context}: #{error.message}", build_backtrace(error)
83
87
  end
84
88
 
85
89
  if error.message.include? 'attempting to push a block that is too old'
86
- raise Steem::BlockTooOldError, "#{context}: #{error.message}", JSON.pretty_generate(error)
90
+ raise Steem::BlockTooOldError, "#{context}: #{error.message}", build_backtrace(error)
87
91
  end
88
92
 
89
93
  if error.message.include? 'irrelevant signature'
90
- raise Steem::IrrelevantSignatureError, "#{context}: #{error.message}", JSON.pretty_generate(error)
94
+ raise Steem::IrrelevantSignatureError, "#{context}: #{error.message}", build_backtrace(error)
91
95
  end
92
96
 
93
97
  if error.message.include? 'missing required posting authority'
94
- raise Steem::MissingPostingAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
98
+ raise Steem::MissingPostingAuthorityError, "#{context}: #{error.message}", build_backtrace(error)
95
99
  end
96
100
 
97
101
  if error.message.include? 'missing required active authority'
98
- raise Steem::MissingActiveAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
102
+ raise Steem::MissingActiveAuthorityError, "#{context}: #{error.message}", build_backtrace(error)
99
103
  end
100
104
 
101
105
  if error.message.include? 'missing required owner authority'
102
- raise Steem::MissingOwnerAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
106
+ raise Steem::MissingOwnerAuthorityError, "#{context}: #{error.message}", build_backtrace(error)
103
107
  end
104
108
 
105
109
  if error.message.include? 'missing required other authority'
106
- raise Steem::MissingOtherAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
110
+ raise Steem::MissingOtherAuthorityError, "#{context}: #{error.message}", build_backtrace(error)
111
+ end
112
+
113
+ if error.message.include? 'Bad or missing upstream response'
114
+ raise Steem::BadOrMissingUpstreamResponseError, "#{context}: #{error.message}", build_backtrace(error)
107
115
  end
108
116
 
109
117
  if error.message.include? 'operator has disabled operation indexing by transaction_id'
110
- raise Steem::TransactionIndexDisabledError, "#{context}: #{error.message}", JSON.pretty_generate(error)
118
+ raise Steem::TransactionIndexDisabledError, "#{context}: #{error.message}", build_backtrace(error)
111
119
  end
112
120
 
113
121
  if error.message.include? 'is_valid_account_name'
114
- raise Steem::InvalidAccountError, "#{context}: #{error.message}", JSON.pretty_generate(error)
122
+ raise Steem::InvalidAccountError, "#{context}: #{error.message}", build_backtrace(error)
115
123
  end
116
124
 
117
125
  if error.message.include? 'Invalid operation name'
118
- raise Steem::UnknownOperationError, "#{context}: #{error.message}", JSON.pretty_generate(error)
126
+ raise Steem::UnknownOperationError, "#{context}: #{error.message}", build_backtrace(error)
127
+ end
128
+
129
+ if error.message =~ /Invalid object name: .+_operation/
130
+ raise Steem::UnknownOperationError, "#{context}: #{error.message}", build_backtrace(error)
119
131
  end
120
132
 
121
133
  if error.message.include? 'Author not found'
122
- raise Steem::AuthorNotFoundError, "#{context}: #{error.message}", JSON.pretty_generate(error)
134
+ raise Steem::AuthorNotFoundError, "#{context}: #{error.message}", build_backtrace(error)
123
135
  end
124
136
 
125
137
  if error.message.include? ' != fc::time_point_sec::maximum()'
126
- raise Steem::ReachedMaximumTimeError, "#{context}: #{error.message}", JSON.pretty_generate(error)
138
+ raise Steem::ReachedMaximumTimeError, "#{context}: #{error.message}", build_backtrace(error)
127
139
  end
128
140
 
129
141
  if error.message.include? 'Cannot transfer a negative amount (aka: stealing)'
130
- raise Steem::TheftError, "#{context}: #{error.message}", JSON.pretty_generate(error)
142
+ raise Steem::TheftError, "#{context}: #{error.message}", build_backtrace(error)
131
143
  end
132
144
 
133
145
  if error.message.include? 'Must transfer a nonzero amount'
134
- raise Steem::NonZeroRequiredError, "#{context}: #{error.message}", JSON.pretty_generate(error)
146
+ raise Steem::NonZeroRequiredError, "#{context}: #{error.message}", build_backtrace(error)
135
147
  end
136
148
 
137
149
  if error.message.include? 'is_asset_type'
138
- raise Steem::UnexpectedAssetError, "#{context}: #{error.message}", JSON.pretty_generate(error)
150
+ raise Steem::UnexpectedAssetError, "#{context}: #{error.message}", build_backtrace(error)
139
151
  end
140
152
 
141
153
  puts JSON.pretty_generate(error) if ENV['DEBUG']
142
- raise UnknownError, "#{context}: #{error.message}", JSON.pretty_generate(error)
154
+ raise UnknownError, "#{context}: #{error.message}", build_backtrace(error)
155
+ end
156
+ private
157
+ def self.build_backtrace(error)
158
+ backtrace = Thread.current.backtrace.reject{ |line| line =~ /base_error/ }
159
+ JSON.pretty_generate(error) + "\n" + backtrace.join("\n")
143
160
  end
144
161
  end
145
162
 
@@ -169,6 +186,7 @@ module Steem
169
186
  class MissingOtherAuthorityError < MissingAuthorityError; end
170
187
  class IncorrectRequestIdError < BaseError; end
171
188
  class IncorrectResponseIdError < BaseError; end
189
+ class BadOrMissingUpstreamResponseError < BaseError; end
172
190
  class TransactionIndexDisabledError < BaseError; end
173
191
  class NotAppBaseError < BaseError; end
174
192
  class UnknownApiError < BaseError; end
@@ -32,7 +32,7 @@ module Steem
32
32
  class Broadcast
33
33
  extend Retriable
34
34
 
35
- DEFAULT_MAX_ACCEPTED_PAYOUT = Type::Amount.new(["1000000000", 3, "@@000000013"])
35
+ DEFAULT_MAX_ACCEPTED_PAYOUT = Type::Amount.new(amount: '1000000000', precision: 3, nai: '@@000000013')
36
36
 
37
37
  # This operation is used to cast a vote on a post/comment.
38
38
  #
@@ -174,9 +174,9 @@ module Steem
174
174
  }]]
175
175
 
176
176
  max_accepted_payout = if params.keys.include? :max_accepted_payout
177
- Type::Amount.to_nia(params[:max_accepted_payout])
177
+ normalize_amount(options.merge amount: params[:max_accepted_payout])
178
178
  else
179
- DEFAULT_MAX_ACCEPTED_PAYOUT.to_nia
179
+ normalize_amount(options.merge amount: DEFAULT_MAX_ACCEPTED_PAYOUT)
180
180
  end
181
181
 
182
182
  allow_votes = if params.keys.include? :allow_votes
@@ -274,7 +274,7 @@ module Steem
274
274
  params = options[:params]
275
275
  check_required_fields(params, *required_fields)
276
276
 
277
- params[:amount] = Type::Amount.to_nia(params[:amount])
277
+ params[:amount] = normalize_amount(options.merge amount: params[:amount])
278
278
 
279
279
  ops = [[:transfer, params]]
280
280
 
@@ -310,7 +310,7 @@ module Steem
310
310
  params = options[:params]
311
311
  check_required_fields(params, *required_fields)
312
312
 
313
- params[:amount] = Type::Amount.to_nia(params[:amount])
313
+ params[:amount] = normalize_amount(options.merge amount: params[:amount])
314
314
 
315
315
  ops = [[:transfer_to_vesting, params]]
316
316
 
@@ -336,7 +336,7 @@ module Steem
336
336
  params = options[:params]
337
337
  check_required_fields(params, *required_fields)
338
338
 
339
- params[:vesting_shares] = Type::Amount.to_nia(params[:vesting_shares])
339
+ params[:vesting_shares] = normalize_amount(options.merge amount: params[:vesting_shares])
340
340
 
341
341
  ops = [[:withdraw_vesting, params]]
342
342
 
@@ -363,8 +363,8 @@ module Steem
363
363
  params = options[:params]
364
364
  check_required_fields(params, *required_fields)
365
365
 
366
- params[:amount_to_sell] = Type::Amount.to_nia(params[:amount_to_sell])
367
- params[:min_to_receive] = Type::Amount.to_nia(params[:min_to_receive])
366
+ params[:amount_to_sell] = normalize_amount(options.merge amount: params[:amount_to_sell])
367
+ params[:min_to_receive] = normalize_amount(options.merge amount: params[:min_to_receive])
368
368
 
369
369
  if !!params[:expiration]
370
370
  params[:expiration] = Time.parse(params[:expiration].to_s)
@@ -414,8 +414,8 @@ module Steem
414
414
  exchange_rate = params[:exchange_rate] rescue nil || {}
415
415
  base = exchange_rate[:base]
416
416
  quote = exchange_rate[:quote]
417
- params[:exchange_rate][:base] = Type::Amount.to_nia(base)
418
- params[:exchange_rate][:quote] = Type::Amount.to_nia(quote)
417
+ params[:exchange_rate][:base] = normalize_amount(options.merge amount: base)
418
+ params[:exchange_rate][:quote] = normalize_amount(options.merge amount: quote)
419
419
 
420
420
  ops = [[:feed_publish, params]]
421
421
 
@@ -438,7 +438,7 @@ module Steem
438
438
  params = options[:params]
439
439
  check_required_fields(params, *required_fields)
440
440
 
441
- params[:amount] = Type::Amount.to_nia(params[:amount])
441
+ params[:amount] = normalize_amount(options.merge amount: params[:amount])
442
442
 
443
443
  ops = [[:convert, params]]
444
444
 
@@ -502,7 +502,7 @@ module Steem
502
502
 
503
503
  check_required_fields(params, *required_fields)
504
504
 
505
- params[:fee] = Type::Amount.to_nia(params[:fee])
505
+ params[:fee] = normalize_amount(options.merge amount: params[:fee])
506
506
 
507
507
  ops = [[:account_create, params]]
508
508
 
@@ -603,8 +603,8 @@ module Steem
603
603
  check_required_fields(params, *required_fields)
604
604
 
605
605
  account_creation_fee = params[:props][:account_creation_fee] rescue nil
606
- params[:props][:account_creation_fee] = Type::Amount.to_nia(account_creation_fee)
607
- params[:fee] = Type::Amount.to_nia(params[:fee])
606
+ params[:props][:account_creation_fee] = normalize_amount(options.merge amount: account_creation_fee)
607
+ params[:fee] = normalize_amount(options.merge amount: params[:fee])
608
608
 
609
609
  ops = [[:witness_update, params]]
610
610
 
@@ -844,9 +844,9 @@ module Steem
844
844
 
845
845
  check_required_fields(params, *required_fields)
846
846
 
847
- params[:sbd_amount] = Type::Amount.to_nia(params[:sbd_amount])
848
- params[:steem_amount] = Type::Amount.to_nia(params[:steem_amount])
849
- params[:fee] = Type::Amount.to_nia(params[:fee])
847
+ params[:sbd_amount] = normalize_amount(options.merge amount: params[:sbd_amount])
848
+ params[:steem_amount] = normalize_amount(options.merge amount: params[:steem_amount])
849
+ params[:fee] = normalize_amount(options.merge amount: params[:fee])
850
850
 
851
851
  params[:ratification_deadline] = Time.parse(params[:ratification_deadline].to_s)
852
852
  params[:ratification_deadline] = params[:ratification_deadline].strftime('%Y-%m-%dT%H:%M:%S')
@@ -905,8 +905,8 @@ module Steem
905
905
  params = options[:params]
906
906
  check_required_fields(params, *required_fields)
907
907
 
908
- params[:sbd_amount] = Type::Amount.to_nia(params[:sbd_amount])
909
- params[:steem_amount] = Type::Amount.to_nia(params[:steem_amount])
908
+ params[:sbd_amount] = normalize_amount(options.merge amount: params[:sbd_amount])
909
+ params[:steem_amount] = normalize_amount(options.merge amount: params[:steem_amount])
910
910
 
911
911
  ops = [[:escrow_release, params]]
912
912
 
@@ -954,7 +954,7 @@ module Steem
954
954
  check_required_fields(params, *required_fields)
955
955
 
956
956
  params[:memo] ||= ''
957
- params[:amount] = Type::Amount.to_nia(params[:amount])
957
+ params[:amount] = normalize_amount(options.merge amount: params[:amount])
958
958
 
959
959
  ops = [[:transfer_to_savings, params]]
960
960
 
@@ -977,7 +977,7 @@ module Steem
977
977
  check_required_fields(params, *required_fields)
978
978
 
979
979
  params[:memo] ||= ''
980
- params[:amount] = Type::Amount.to_nia(params[:amount])
980
+ params[:amount] = normalize_amount(options.merge amount: params[:amount])
981
981
 
982
982
  ops = [[:transfer_from_savings, params]]
983
983
 
@@ -1039,7 +1039,7 @@ module Steem
1039
1039
  params = options[:params]
1040
1040
  check_required_fields(params, *required_fields)
1041
1041
 
1042
- params[:vesting_shares] = Type::Amount.to_nia(params[:vesting_shares])
1042
+ params[:vesting_shares] = normalize_amount(options.merge amount: params[:vesting_shares])
1043
1043
  ops = [[:delegate_vesting_shares, params]]
1044
1044
 
1045
1045
  process(options.merge(ops: ops), &block)
@@ -1075,8 +1075,8 @@ module Steem
1075
1075
 
1076
1076
  check_required_fields(params, *required_fields)
1077
1077
 
1078
- params[:fee] = Type::Amount.to_nia(params[:fee])
1079
- params[:delegation] = Type::Amount.to_nia(params[:delegation])
1078
+ params[:fee] = normalize_amount(options.merge amount: params[:fee])
1079
+ params[:delegation] = normalize_amount(options.merge amount: params[:delegation])
1080
1080
  params[:extensions] ||= []
1081
1081
 
1082
1082
  ops = [[:account_create_with_delegation, params]]
@@ -1097,9 +1097,17 @@ module Steem
1097
1097
  trx = tx.transaction
1098
1098
 
1099
1099
  response = if !!options[:pretend]
1100
- database_api(options).verify_authority(trx: trx)
1100
+ if !!options[:app_base]
1101
+ database_api(options).verify_authority(trx: trx)
1102
+ else
1103
+ database_api(options).verify_authority(trx)
1104
+ end
1101
1105
  else
1102
- network_broadcast_api(options).broadcast_transaction_synchronous(trx: trx)
1106
+ if !!options[:app_base]
1107
+ network_broadcast_api(options).broadcast_transaction(trx: trx)
1108
+ else
1109
+ network_broadcast_api(options).broadcast_transaction_synchronous(trx)
1110
+ end
1103
1111
  end
1104
1112
 
1105
1113
  break
@@ -1120,13 +1128,30 @@ module Steem
1120
1128
  end
1121
1129
  private
1122
1130
  # @private
1131
+ def self.normalize_amount(options)
1132
+ if !!options[:app_base]
1133
+ Type::Amount.to_h(options[:amount])
1134
+ else
1135
+ Type::Amount.to_s(options[:amount])
1136
+ end
1137
+ end
1138
+
1139
+ # @privats
1123
1140
  def self.database_api(options)
1124
- options[:database_api] ||= Steem::DatabaseApi.new(options)
1141
+ options[:database_api] ||= if !!options[:app_base]
1142
+ Steem::DatabaseApi.new(options)
1143
+ else
1144
+ Steem::CondenserApi.new(options)
1145
+ end
1125
1146
  end
1126
1147
 
1127
1148
  # @private
1128
1149
  def self.network_broadcast_api(options)
1129
- options[:network_broadcast_api] ||= Steem::NetworkBroadcastApi.new(options)
1150
+ options[:network_broadcast_api] ||= if !!options[:app_base]
1151
+ Steem::NetworkBroadcaseApi.new(options)
1152
+ else
1153
+ Steem::CondenserApi.new(options)
1154
+ end
1130
1155
  end
1131
1156
 
1132
1157
  # @private
@@ -1,12 +1,12 @@
1
1
  module Steem
2
2
  module Retriable
3
3
  # @private
4
- MAX_RETRY_COUNT = 100
4
+ MAX_RETRY_COUNT = 30
5
5
 
6
- # @private
7
- MAX_BACKOFF = 30
6
+ MAX_RETRY_ELAPSE = 60
8
7
 
9
- MAX_RETRY_ELAPSE = 300
8
+ # @private
9
+ MAX_BACKOFF = MAX_RETRY_ELAPSE / 4
10
10
 
11
11
  RETRYABLE_EXCEPTIONS = [
12
12
  NonCanonicalSignatureError, IncorrectRequestIdError,
@@ -19,14 +19,7 @@ module Steem
19
19
  def backoff
20
20
  @backoff ||= 0.1
21
21
  @backoff *= 2
22
- if @backoff > MAX_BACKOFF
23
- @backoff = 0.1
24
-
25
- if Time.now.utc - @first_retry_at > MAX_RETRY_ELAPSE
26
- @retry_count = nil
27
- @first_retry_at = nil
28
- end
29
- end
22
+ @backoff = 0.1 if @backoff > MAX_BACKOFF
30
23
 
31
24
  sleep @backoff
32
25
  end
@@ -37,7 +30,11 @@ module Steem
37
30
 
38
31
  return false if @retry_count >= MAX_RETRY_COUNT
39
32
 
40
- @retry_count += 1
33
+ @retry_count = if Time.now.utc - @first_retry_at > MAX_RETRY_ELAPSE
34
+ @first_retry_at = nil
35
+ else
36
+ @retry_count + 1
37
+ end
41
38
 
42
39
  can_retry = case e
43
40
  when *RETRYABLE_EXCEPTIONS then true
@@ -118,7 +118,7 @@ module Steem
118
118
  error = response['error'].to_json if !!response['error']
119
119
 
120
120
  if req_id != res_id
121
- raise IncorrectResponseIdError, "#{method}: The json-rpc id did not match. Request was: #{req_id}, got: #{res_id.inspect}", error.nil? ? nil : error.to_json
121
+ raise IncorrectResponseIdError, "#{method}: The json-rpc id did not match. Request was: #{req_id}, got: #{res_id.inspect}", BaseError.send(:build_backtrace, error)
122
122
  end
123
123
  end
124
124
 
@@ -143,7 +143,7 @@ module Steem
143
143
  raise TooManyTimeoutsError.new("Too many timeouts for: #{context}", cause)
144
144
  elsif @timeout_retry_count % 10 == 0
145
145
  msg = "#{@timeout_retry_count} retry attempts for: #{context}"
146
- msg += "; cause: #{e}" if !!cause
146
+ msg += "; cause: #{cause}" if !!cause
147
147
  error_pipe.puts msg
148
148
  end
149
149
 
@@ -30,7 +30,7 @@ module Steem
30
30
  def http
31
31
  @http ||= Net::HTTP.new(uri.host, uri.port).tap do |http|
32
32
  http.use_ssl = true if uri.to_s =~ /^https/i
33
- http.keep_alive_timeout = 2 # seconds
33
+ http.keep_alive_timeout = 150 # seconds
34
34
 
35
35
  # WARNING This method opens a serious security hole. Never use this
36
36
  # method in production code.
@@ -15,7 +15,7 @@ module Steem
15
15
  # })
16
16
  #
17
17
  # trx = builder.transaction
18
- # network_broadcast_api = Steem::NetworkBroadcastApi.new
18
+ # network_broadcast_api = Steem::CondenserApi.new
19
19
  # network_broadcast_api.broadcast_transaction_synchronous(trx: trx)
20
20
  #
21
21
  #
@@ -26,13 +26,25 @@ module Steem
26
26
  include ChainConfig
27
27
  include Utils
28
28
 
29
- attr_accessor :database_api, :block_api, :expiration, :operations
29
+ attr_accessor :app_base, :database_api, :block_api, :expiration, :operations
30
30
  attr_writer :wif
31
31
  attr_reader :signed
32
32
 
33
+ alias app_base? app_base
34
+
33
35
  def initialize(options = {})
34
- @database_api = options[:database_api] || Steem::DatabaseApi.new(options)
35
- @block_api = options[:block_api] || Steem::BlockApi.new(options)
36
+ @app_base = !!options[:app_base] # default false
37
+ @database_api = options[:database_api]
38
+ @block_api = options[:block_api]
39
+
40
+ if app_base?
41
+ @database_api ||= Steem::DatabaseApi.new(options)
42
+ @block_api ||= Steem::BlockApi.new(options)
43
+ else
44
+ @database_api ||= Steem::CondenserApi.new(options)
45
+ @block_api ||= Steem::CondenserApi.new(options)
46
+ end
47
+
36
48
  @wif = [options[:wif]].flatten
37
49
  @signed = false
38
50
 
@@ -114,9 +126,18 @@ module Steem
114
126
  catch :prepare_header do; begin
115
127
  @database_api.get_dynamic_global_properties do |properties|
116
128
  block_number = properties.last_irreversible_block_num
129
+ block_header_args = if app_base?
130
+ {block_num: block_number}
131
+ else
132
+ block_number
133
+ end
117
134
 
118
- @block_api.get_block_header(block_num: block_number) do |result|
119
- header = result.header
135
+ @block_api.get_block_header(block_header_args) do |result|
136
+ header = if app_base?
137
+ result.header
138
+ else
139
+ result
140
+ end
120
141
 
121
142
  @ref_block_num = (block_number - 1) & 0xFFFF
122
143
  @ref_block_prefix = unhexlify(header.previous[8..-1]).unpack('V*')[0]
@@ -138,7 +159,7 @@ module Steem
138
159
 
139
160
  # Sets operations all at once, then prepares.
140
161
  def operations=(operations)
141
- @operations = operations
162
+ @operations = operations.map{ |op| normalize_operation(op) }
142
163
  prepare
143
164
  @operations
144
165
  end
@@ -167,34 +188,8 @@ module Steem
167
188
  # @return {TransactionBuilder}
168
189
  def put(type, op = nil)
169
190
  @expiration = nil
170
-
171
- ## Saving this for later. This block, or something like it, might replace
172
- ## API broadcast operation structure.
173
- # case type
174
- # when Symbol, String
175
- # type_value = "#{type}_operation"
176
- # @operations << {type: type_value, value: op}
177
- # when Hash
178
- # type_value = "#{type.keys.first}_operation"
179
- # @operations << {type: type_value, value: type.values.first}
180
- # when Array
181
- # type_value = "#{type[0]}_operation"
182
- # @operations << {type: type_value, value: type[1]}
183
- # else
184
- # # don't know what to do with it, skipped
185
- # end
186
-
187
- case type
188
- when Symbol then @operations << [type, op]
189
- when String then @operations << [type.to_sym, op]
190
- when Hash then @operations << [type.keys.first.to_sym, type.values.first]
191
- when Array then @operations << type
192
- else
193
- # don't know what to do with it, skipped
194
- end
195
-
191
+ @operations << normalize_operation(type, op)
196
192
  prepare
197
-
198
193
  self
199
194
  end
200
195
 
@@ -240,8 +235,20 @@ module Steem
240
235
 
241
236
  unless @signed
242
237
  catch :serialize do; begin
243
- @database_api.get_transaction_hex(trx: trx) do |result|
244
- hex = @chain_id + result.hex[0..-4] # Why do we have to chop the last two bytes?
238
+ transaction_hex_args = if app_base?
239
+ {trx: trx}
240
+ else
241
+ trx
242
+ end
243
+
244
+ @database_api.get_transaction_hex(transaction_hex_args) do |result|
245
+ hex = if app_base?
246
+ result.hex
247
+ else
248
+ result
249
+ end
250
+
251
+ hex = @chain_id + hex[0..-4] # Why do we have to chop the last two bytes?
245
252
  digest = unhexlify(hex)
246
253
  digest_hex = Digest::SHA256.digest(digest)
247
254
  private_keys = @wif.map{ |wif| Bitcoin::Key.from_base58 wif }
@@ -283,8 +290,18 @@ module Steem
283
290
 
284
291
  # @return [Array] All public keys that could possibly sign for a given transaction.
285
292
  def potential_signatures
286
- @database_api.get_potential_signatures(trx: transaction) do |result|
287
- result[:keys]
293
+ potential_signatures_args = if app_base?
294
+ {trx: transaction}
295
+ else
296
+ transaction
297
+ end
298
+
299
+ @database_api.get_potential_signatures(potential_signatures_args) do |result|
300
+ if app_base?
301
+ result[:keys]
302
+ else
303
+ result
304
+ end
288
305
  end
289
306
  end
290
307
 
@@ -294,15 +311,35 @@ module Steem
294
311
  #
295
312
  # @return [Array] The minimal subset of public keys that should add signatures to the transaction.
296
313
  def required_signatures
297
- @database_api.get_required_signatures(trx: transaction) do |result|
298
- result[:keys]
314
+ required_signatures_args = if app_base?
315
+ {trx: transaction}
316
+ else
317
+ [transaction, []]
318
+ end
319
+
320
+ @database_api.get_required_signatures(*required_signatures_args) do |result|
321
+ if app_base?
322
+ result[:keys]
323
+ else
324
+ result
325
+ end
299
326
  end
300
327
  end
301
328
 
302
329
  # @return [Boolean] True if the transaction has all of the required signatures.
303
330
  def valid?
304
- @database_api.verify_authority(trx: transaction) do |result|
305
- result.valid
331
+ verify_authority_args = if app_base?
332
+ {trx: transaction}
333
+ else
334
+ transaction
335
+ end
336
+
337
+ @database_api.verify_authority(verify_authority_args) do |result|
338
+ if app_base?
339
+ result.valid
340
+ else
341
+ result
342
+ end
306
343
  end
307
344
  end
308
345
  private
@@ -318,5 +355,32 @@ module Steem
318
355
  ((sig[33] & 0x80 ) != 0)
319
356
  )
320
357
  end
358
+
359
+ def normalize_operation(type, op = nil)
360
+ if app_base?
361
+ case type
362
+ when Symbol, String
363
+ type_value = "#{type}_operation"
364
+ {type: type_value, value: op}
365
+ when Hash
366
+ type_value = "#{type.keys.first}_operation"
367
+ {type: type_value, value: type.values.first}
368
+ when Array
369
+ type_value = "#{type[0]}_operation"
370
+ {type: type_value, value: type[1]}
371
+ else
372
+ raise Steem::ArgumentError, "Don't know what to do with operation type #{type.class}: #{type} (#{op})"
373
+ end
374
+ else
375
+ case type
376
+ when Symbol then [type, op]
377
+ when String then [type.to_sym, op]
378
+ when Hash then [type.keys.first.to_sym, type.values.first]
379
+ when Array then type
380
+ else
381
+ raise Steem::ArgumentError, "Don't know what to do with operation type #{type.class}: #{type} (#{op})"
382
+ end
383
+ end
384
+ end
321
385
  end
322
386
  end
@@ -3,8 +3,10 @@ module Steem
3
3
 
4
4
  # See: https://github.com/xeroc/piston-lib/blob/34a7525cee119ec9b24a99577ede2d54466fca0e/steembase/operations.py
5
5
  class Amount < BaseType
6
- def self.to_nia(amount)
7
- new(amount).to_nia
6
+ attr_reader :amount, :precision, :nai, :asset
7
+
8
+ def self.to_h(amount)
9
+ new(amount).to_h
8
10
  end
9
11
 
10
12
  def self.to_s(amount)
@@ -16,15 +18,33 @@ module Steem
16
18
 
17
19
  case value
18
20
  when Array
19
- a, p, t = value
20
- @asset = case t
21
+ @amount, @precision, @nai = value
22
+ @asset = case @nai
21
23
  when '@@000000013' then 'SBD'
22
24
  when '@@000000021' then 'STEEM'
23
25
  when '@@000000037' then 'VESTS'
24
- else; raise TypeError, "Asset #{@asset} unknown."
26
+ else; raise TypeError, "Asset #{@nai} unknown."
27
+ end
28
+
29
+ @amount = "%.#{@precision}f" % (@amount.to_f / 10 ** @precision)
30
+ when Hash
31
+ @amount, @precision, @nai = value.map do |k, v|
32
+ v if %i(amount precision nai).include? k.to_sym
33
+ end.compact
34
+
35
+ @asset = case @nai
36
+ when '@@000000013' then 'SBD'
37
+ when '@@000000021' then 'STEEM'
38
+ when '@@000000037' then 'VESTS'
39
+ else; raise TypeError, "Asset #{@nai} unknown."
25
40
  end
26
- @precision = p
27
- @amount = "%.#{p}f" % (a.to_f / 10 ** p)
41
+
42
+ @amount = "%.#{@precision}f" % (@amount.to_f / 10 ** @precision)
43
+ when Amount
44
+ @precision = value.precision
45
+ @nai = value.nai
46
+ @asset = value.asset
47
+ @amount = value.amount
28
48
  else
29
49
  @amount, @asset = value.strip.split(' ') rescue ['', '']
30
50
  @precision = case @asset
@@ -45,7 +65,7 @@ module Steem
45
65
  asset
46
66
  end
47
67
 
48
- def to_nia
68
+ def to_a
49
69
  case @asset
50
70
  when 'STEEM' then [(@amount.to_f * 1000).to_i.to_s, 3, '@@000000021']
51
71
  when 'VESTS' then [(@amount.to_f * 1000000).to_i.to_s, 6, '@@000000037']
@@ -53,6 +73,26 @@ module Steem
53
73
  end
54
74
  end
55
75
 
76
+ def to_h
77
+ case @asset
78
+ when 'STEEM' then {
79
+ amount: (@amount.to_f * 1000).to_i.to_s,
80
+ precision: 3,
81
+ nai: '@@000000021'
82
+ }
83
+ when 'VESTS' then {
84
+ amount: (@amount.to_f * 1000000).to_i.to_s,
85
+ precision: 6,
86
+ nai: '@@000000037'
87
+ }
88
+ when 'SBD' then {
89
+ amount: (@amount.to_f * 1000).to_i.to_s,
90
+ precision: 3,
91
+ nai: '@@000000013'
92
+ }
93
+ end
94
+ end
95
+
56
96
  def to_s
57
97
  "#{@amount} #{@asset}"
58
98
  end
data/lib/steem/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Steem
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.1'
3
3
  AGENT_ID = "steem-ruby/#{VERSION}"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steem-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Martin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-29 00:00:00.000000000 Z
11
+ date: 2018-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler