radiator 0.2.0a

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.
@@ -0,0 +1,168 @@
1
+ require 'uri'
2
+ require 'base64'
3
+ require 'hashie'
4
+ require 'hashie/logger'
5
+ require 'openssl'
6
+ require 'net/http/persistent'
7
+
8
+ module Radiator
9
+ class Api
10
+ def initialize(options = {})
11
+ @user = options[:user]
12
+ @password = options[:password]
13
+ @url = options[:url] || 'https://steemd.steemit.com'
14
+ @debug = !!options[:debug]
15
+ @net_http_persistent_enabled = true
16
+ @logger = options[:logger] || Radiator.logger
17
+
18
+ Hashie.logger = @logger
19
+ @method_names = nil
20
+ end
21
+
22
+ def method_names
23
+ return @method_names if !!@method_names
24
+
25
+ @method_names = Radiator::Api.methods(api_name).map do |e|
26
+ e['method'].to_sym
27
+ end
28
+ end
29
+
30
+ def api_name
31
+ :database_api
32
+ end
33
+
34
+ # Get a specific block or range of blocks.
35
+ #
36
+ # @param block_number [Fixnum || Array<Fixnum>]
37
+ # @param block the block to execute for each result, optional.
38
+ # @return [Array]
39
+ def get_blocks(block_number, &block)
40
+ block_number = [*(block_number)].flatten
41
+
42
+ if !!block
43
+ block_number.each do |i|
44
+ yield get_block(i).result, i
45
+ end
46
+ else
47
+ block_number.map do |i|
48
+ get_block(i).result
49
+ end
50
+ end
51
+ end
52
+
53
+ # Find a specific block
54
+ #
55
+ # @param block_number [Fixnum]
56
+ # @param block the block to execute for each result, optional.
57
+ # @return [Hash]
58
+ def find_block(block_number, &block)
59
+ if !!block
60
+ yield get_blocks(block_number).result
61
+ else
62
+ get_blocks(block_number).result
63
+ end
64
+ end
65
+
66
+ def find_account(id, &block)
67
+ if !!block
68
+ yield get_accounts([id]).result.first
69
+ else
70
+ get_accounts([id]).result.first
71
+ end
72
+ end
73
+
74
+ # TODO: Need to rename this to base_per_mvest and alias to steem_per_mvest
75
+ def steem_per_mvest
76
+ properties = get_dynamic_global_properties.result
77
+
78
+ total_vesting_fund_steem = properties.total_vesting_fund_steem.to_f
79
+ total_vesting_shares_mvest = properties.total_vesting_shares.to_f / 1e6
80
+
81
+ total_vesting_fund_steem / total_vesting_shares_mvest
82
+ end
83
+
84
+ # TODO: Need to rename this to base_per_debt and alias to steem_per_debt
85
+ def steem_per_usd
86
+ feed_history = get_feed_history.result
87
+
88
+ current_median_history = feed_history.current_median_history
89
+ base = current_median_history.base
90
+ base = base.split(' ').first.to_f
91
+ quote = current_median_history.quote
92
+ quote = quote.split(' ').first.to_f
93
+
94
+ (base / quote) * steem_per_mvest
95
+ end
96
+
97
+ def respond_to_missing?(m, include_private = false)
98
+ method_names.include?(m.to_sym)
99
+ end
100
+
101
+ def method_missing(m, *args, &block)
102
+ super unless respond_to_missing?(m)
103
+
104
+ options = {
105
+ jsonrpc: "2.0",
106
+ params: [api_name, m, args],
107
+ id: rpc_id,
108
+ method: "call"
109
+ }
110
+
111
+ response = request(options)
112
+
113
+ if !!response
114
+ response = JSON[response.body]
115
+
116
+ Hashie::Mash.new(response)
117
+ end
118
+ end
119
+
120
+ def shutdown
121
+ @http.shutdown if !!@http && defined?(@http.shutdown)
122
+ @http = nil
123
+ end
124
+ private
125
+ def self.methods_json_path
126
+ @methods_json_path ||= "#{File.dirname(__FILE__)}/methods.json"
127
+ end
128
+
129
+ def self.methods(api_name)
130
+ @methods ||= {}
131
+ @methods[api_name] ||= JSON[File.read methods_json_path].map do |e|
132
+ e if e['api'].to_sym == api_name
133
+ end.compact.freeze
134
+ end
135
+
136
+ def rpc_id
137
+ @rpc_id ||= 0
138
+ @rpc_id = @rpc_id + 1
139
+ end
140
+
141
+ def uri
142
+ @uri ||= URI.parse(@url)
143
+ end
144
+
145
+ def http
146
+ @http ||= Net::HTTP::Persistent.new "radiator-#{Radiator::VERSION}-#{self.class.name.downcase}"
147
+ end
148
+
149
+ def request(options)
150
+ if !!@net_http_persistent_enabled
151
+ begin
152
+ request = Net::HTTP::Post.new uri.request_uri, 'Content-Type' => 'application/json'
153
+ request.body = JSON[options]
154
+ return http.request(uri, request)
155
+ rescue Net::HTTP::Persistent::Error
156
+ @net_http_persistent_enabled = false
157
+ end
158
+ end
159
+
160
+ unless @net_http_persistent_enabled
161
+ @http = Net::HTTP.new(uri.host, uri.port)
162
+ request = Net::HTTP::Post.new uri.request_uri, 'Content-Type' => 'application/json'
163
+ request.body = JSON[options]
164
+ @http.request(request)
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,17 @@
1
+ module Radiator
2
+ class BaseError < StandardError
3
+ def initialize(error)
4
+ @error = error
5
+ end
6
+
7
+ def to_s
8
+ JSON[@error] rescue @error
9
+ end
10
+ end
11
+ end
12
+
13
+ module Radiator; class ApiError < BaseError; end; end
14
+ module Radiator; class StreamError < BaseError; end; end
15
+ module Radiator; class TypeError < BaseError; end; end
16
+ module Radiator; class OperationError < BaseError; end; end
17
+ module Radiator; class TransactionError < BaseError; end; end
@@ -0,0 +1,489 @@
1
+ // Copied from:
2
+ // https://raw.githubusercontent.com/steemit/steem-js/master/src/broadcast/operations.json
3
+
4
+ [
5
+ {
6
+ "roles": ["posting"],
7
+ "operation": "vote",
8
+ "params": [
9
+ "voter",
10
+ "author",
11
+ "permlink",
12
+ "weight"
13
+ ]
14
+ },
15
+ {
16
+ "roles": ["posting"],
17
+ "operation": "comment",
18
+ "params": [
19
+ "parent_author",
20
+ "parent_permlink",
21
+ "author",
22
+ "permlink",
23
+ "title",
24
+ "body",
25
+ "json_metadata"
26
+ ]
27
+ },
28
+ {
29
+ "roles": ["active", "owner"],
30
+ "operation": "transfer",
31
+ "params": [
32
+ "from",
33
+ "to",
34
+ "amount",
35
+ "memo"
36
+ ]
37
+ },
38
+ {
39
+ "roles": ["active"],
40
+ "operation": "transfer_to_vesting",
41
+ "params": [
42
+ "from",
43
+ "to",
44
+ "amount"
45
+ ]
46
+ },
47
+ {
48
+ "roles": ["active"],
49
+ "operation": "withdraw_vesting",
50
+ "params": [
51
+ "account",
52
+ "vesting_shares"
53
+ ]
54
+ },
55
+ {
56
+ "roles": ["active"],
57
+ "operation": "limit_order_create",
58
+ "params": [
59
+ "owner",
60
+ "orderid",
61
+ "amount_to_sell",
62
+ "min_to_receive",
63
+ "fill_or_kill",
64
+ "expiration"
65
+ ]
66
+ },
67
+ {
68
+ "roles": ["active"],
69
+ "operation": "limit_order_cancel",
70
+ "params": [
71
+ "owner",
72
+ "orderid"
73
+ ]
74
+ },
75
+ {
76
+ "roles": ["active"],
77
+ "operation": "price",
78
+ "params": [
79
+ "base",
80
+ "quote"
81
+ ]
82
+ },
83
+ {
84
+ "roles": ["active"],
85
+ "operation": "feed_publish",
86
+ "params": [
87
+ "publisher",
88
+ "exchange_rate"
89
+ ]
90
+ },
91
+ {
92
+ "roles": ["active"],
93
+ "operation": "convert",
94
+ "params": [
95
+ "owner",
96
+ "requestid",
97
+ "amount"
98
+ ]
99
+ },
100
+ {
101
+ "roles": ["active"],
102
+ "operation": "account_create",
103
+ "params": [
104
+ "fee",
105
+ "creator",
106
+ "new_account_name",
107
+ "owner",
108
+ "active",
109
+ "posting",
110
+ "memo_key",
111
+ "json_metadata"
112
+ ]
113
+ },
114
+ {
115
+ "roles": ["owner", "active"],
116
+ "operation": "account_update",
117
+ "params": [
118
+ "account",
119
+ "owner",
120
+ "active",
121
+ "posting",
122
+ "memo_key",
123
+ "json_metadata"
124
+ ]
125
+ },
126
+ {
127
+ "roles": ["active"],
128
+ "operation": "witness_update",
129
+ "params": [
130
+ "owner",
131
+ "url",
132
+ "block_signing_key",
133
+ "props",
134
+ "fee"
135
+ ]
136
+ },
137
+ {
138
+ "roles": ["posting"],
139
+ "operation": "account_witness_vote",
140
+ "params": [
141
+ "account",
142
+ "witness",
143
+ "approve"
144
+ ]
145
+ },
146
+ {
147
+ "roles": ["posting"],
148
+ "operation": "account_witness_proxy",
149
+ "params": [
150
+ "account",
151
+ "proxy"
152
+ ]
153
+ },
154
+ {
155
+ "roles": ["active"],
156
+ "operation": "pow",
157
+ "params": [
158
+ "worker",
159
+ "input",
160
+ "signature",
161
+ "work"
162
+ ]
163
+ },
164
+ {
165
+ "roles": ["active"],
166
+ "operation": "custom",
167
+ "params": [
168
+ "required_auths",
169
+ "id",
170
+ "data"
171
+ ]
172
+ },
173
+ {
174
+ "roles": ["posting"],
175
+ "operation": "delete_comment",
176
+ "params": [
177
+ "author",
178
+ "permlink"
179
+ ]
180
+ },
181
+ {
182
+ "roles": ["posting", "active"],
183
+ "operation": "custom_json",
184
+ "params": [
185
+ "required_auths",
186
+ "required_posting_auths",
187
+ "id",
188
+ "json"
189
+ ]
190
+ },
191
+ {
192
+ "roles": ["posting"],
193
+ "operation": "comment_options",
194
+ "params": [
195
+ "author",
196
+ "permlink",
197
+ "max_accepted_payout",
198
+ "percent_steem_dollars",
199
+ "allow_votes",
200
+ "allow_curation_rewards",
201
+ "extensions"
202
+ ]
203
+ },
204
+ {
205
+ "roles": ["active"],
206
+ "operation": "set_withdraw_vesting_route",
207
+ "params": [
208
+ "from_account",
209
+ "to_account",
210
+ "percent",
211
+ "auto_vest"
212
+ ]
213
+ },
214
+ {
215
+ "roles": ["active"],
216
+ "operation": "limit_order_create2",
217
+ "params": [
218
+ "owner",
219
+ "orderid",
220
+ "amount_to_sell",
221
+ "exchange_rate",
222
+ "fill_or_kill",
223
+ "expiration"
224
+ ]
225
+ },
226
+ {
227
+ "roles": ["posting"],
228
+ "operation": "challenge_authority",
229
+ "params": [
230
+ "challenger",
231
+ "challenged",
232
+ "require_owner"
233
+ ]
234
+ },
235
+ {
236
+ "roles": ["active", "owner"],
237
+ "operation": "prove_authority",
238
+ "params": [
239
+ "challenged",
240
+ "require_owner"
241
+ ]
242
+ },
243
+ {
244
+ "roles": ["active"],
245
+ "operation": "request_account_recovery",
246
+ "params": [
247
+ "recovery_account",
248
+ "account_to_recover",
249
+ "new_owner_authority",
250
+ "extensions"
251
+ ]
252
+ },
253
+ {
254
+ "roles": ["owner"],
255
+ "operation": "change_recovery_account",
256
+ "params": [
257
+ "account_to_recover",
258
+ "new_recovery_account",
259
+ "extensions"
260
+ ]
261
+ },
262
+ {
263
+ "roles": ["active"],
264
+ "operation": "escrow_transfer",
265
+ "params": [
266
+ "from",
267
+ "to",
268
+ "agent",
269
+ "escrow_id",
270
+ "sbd_amount",
271
+ "steem_amount",
272
+ "fee",
273
+ "ratification_deadline",
274
+ "escrow_expiration",
275
+ "json_meta"
276
+ ]
277
+ },
278
+ {
279
+ "roles": ["active"],
280
+ "operation": "escrow_dispute",
281
+ "params": [
282
+ "from",
283
+ "to",
284
+ "agent",
285
+ "who",
286
+ "escrow_id"
287
+ ]
288
+ },
289
+ {
290
+ "roles": ["active"],
291
+ "operation": "escrow_release",
292
+ "params": [
293
+ "from",
294
+ "to",
295
+ "agent",
296
+ "who",
297
+ "receiver",
298
+ "escrow_id",
299
+ "sbd_amount",
300
+ "steem_amount"
301
+ ]
302
+ },
303
+ {
304
+ "roles": ["active"],
305
+ "operation": "pow2",
306
+ "params": [
307
+ "input",
308
+ "pow_summary"
309
+ ]
310
+ },
311
+ {
312
+ "roles": ["active"],
313
+ "operation": "escrow_approve",
314
+ "params": [
315
+ "from",
316
+ "to",
317
+ "agent",
318
+ "who",
319
+ "escrow_id",
320
+ "approve"
321
+ ]
322
+ },
323
+ {
324
+ "roles": ["active"],
325
+ "operation": "transfer_to_savings",
326
+ "params": [
327
+ "from",
328
+ "to",
329
+ "amount",
330
+ "memo"
331
+ ]
332
+ },
333
+ {
334
+ "roles": ["active"],
335
+ "operation": "transfer_from_savings",
336
+ "params": [
337
+ "from",
338
+ "request_id",
339
+ "to",
340
+ "amount",
341
+ "memo"
342
+ ]
343
+ },
344
+ {
345
+ "roles": ["active"],
346
+ "operation": "cancel_transfer_from_savings",
347
+ "params": [
348
+ "from",
349
+ "request_id"
350
+ ]
351
+ },
352
+ {
353
+ "roles": ["posting", "active", "owner"],
354
+ "operation": "custom_binary",
355
+ "params": [
356
+ "id",
357
+ "data"
358
+ ]
359
+ },
360
+ {
361
+ "roles": ["owner"],
362
+ "operation": "decline_voting_rights",
363
+ "params": [
364
+ "account",
365
+ "decline"
366
+ ]
367
+ },
368
+ {
369
+ "roles": ["active"],
370
+ "operation": "reset_account",
371
+ "params": [
372
+ "reset_account",
373
+ "account_to_reset",
374
+ "new_owner_authority"
375
+ ]
376
+ },
377
+ {
378
+ "roles": ["owner", "posting"],
379
+ "operation": "set_reset_account",
380
+ "params": [
381
+ "account",
382
+ "current_reset_account",
383
+ "reset_account"
384
+ ]
385
+ },
386
+ {
387
+ "roles": ["posting"],
388
+ "operation": "claim_reward_balance",
389
+ "params": [
390
+ "account",
391
+ "reward_steem",
392
+ "reward_sbd",
393
+ "reward_vests"
394
+ ]
395
+ },
396
+ {
397
+ "roles": ["active"],
398
+ "operation": "delegate_vesting_shares",
399
+ "params": [
400
+ "delegator",
401
+ "delegatee",
402
+ "vesting_shares"
403
+ ]
404
+ },
405
+ {
406
+ "roles": ["active"],
407
+ "operation": "account_create_with_delegation",
408
+ "params": [
409
+ "fee",
410
+ "delegation",
411
+ "creator",
412
+ "new_account_name",
413
+ "owner",
414
+ "active",
415
+ "posting",
416
+ "memo_key",
417
+ "json_metadata",
418
+ "extensions"
419
+ ]
420
+ },
421
+ {
422
+ "roles": ["active"],
423
+ "operation": "fill_convert_request",
424
+ "params": [
425
+ "owner",
426
+ "requestid",
427
+ "amount_in",
428
+ "amount_out"
429
+ ]
430
+ },
431
+ {
432
+ "roles": ["posting"],
433
+ "operation": "comment_reward",
434
+ "params": [
435
+ "author",
436
+ "permlink",
437
+ "payout"
438
+ ]
439
+ },
440
+ {
441
+ "roles": ["active"],
442
+ "operation": "liquidity_reward",
443
+ "params": [
444
+ "owner",
445
+ "payout"
446
+ ]
447
+ },
448
+ {
449
+ "roles": ["active"],
450
+ "operation": "interest",
451
+ "params": [
452
+ "owner",
453
+ "interest"
454
+ ]
455
+ },
456
+ {
457
+ "roles": ["active"],
458
+ "operation": "fill_vesting_withdraw",
459
+ "params": [
460
+ "from_account",
461
+ "to_account",
462
+ "withdrawn",
463
+ "deposited"
464
+ ]
465
+ },
466
+ {
467
+ "roles": ["posting"],
468
+ "operation": "fill_order",
469
+ "params": [
470
+ "current_owner",
471
+ "current_orderid",
472
+ "current_pays",
473
+ "open_owner",
474
+ "open_orderid",
475
+ "open_pays"
476
+ ]
477
+ },
478
+ {
479
+ "roles": ["posting"],
480
+ "operation": "fill_transfer_from_savings",
481
+ "params": [
482
+ "from",
483
+ "to",
484
+ "amount",
485
+ "request_id",
486
+ "memo"
487
+ ]
488
+ }
489
+ ]
@@ -0,0 +1,29 @@
1
+ module Radiator
2
+ module ChainConfig
3
+ EXPIRE_IN_SECS = 15
4
+ EXPIRE_IN_SECS_PROPOSAL = 24 * 60 * 60
5
+
6
+ NETWORKS_STEEM_CHAIN_ID = '0000000000000000000000000000000000000000000000000000000000000000'
7
+ NETWORKS_STEEM_ADDRESS_PREFIX = 'STM'
8
+ NETWORKS_STEEM_CORE_ASSET = 'STEEM'
9
+ NETWORKS_STEEM_DEBT_ASSET = 'SBD'
10
+ NETWORKS_STEEM_VEST_ASSET = 'VESTS'
11
+ NETWORKS_STEEM_DEFAULT_NODE = 'https://steemd.steemit.com'
12
+
13
+ NETWORKS_GOLOS_CHAIN_ID = '782a3039b478c839e4cb0c941ff4eaeb7df40bdd68bd441afd444b9da763de12'
14
+ NETWORKS_GOLOS_ADDRESS_PREFIX = 'GLS'
15
+ NETWORKS_GOLOS_CORE_ASSET = 'GOLOS'
16
+ NETWORKS_GOLOS_DEBT_ASSET = 'GBG'
17
+ NETWORKS_GOLOS_VEST_ASSET = 'GESTS'
18
+ NETWORKS_GOLOS_DEFAULT_NODE = 'https://node.golos.ws'
19
+
20
+ NETWORKS_TEST_CHAIN_ID = '18dcf0a285365fc58b71f18b3d3fec954aa0c141c44e4e5cb4cf777b9eab274e'
21
+ NETWORKS_TEST_ADDRESS_PREFIX = 'TST'
22
+ NETWORKS_TEST_CORE_ASSET = 'CORE'
23
+ NETWORKS_TEST_DEBT_ASSET = 'TEST'
24
+ NETWORKS_TEST_VEST_ASSET = 'CESTS'
25
+ NETWORKS_TEST_DEFAULT_NODE = 'https://test.steem.ws'
26
+
27
+ NETWORK_CHAIN_IDS = [NETWORKS_STEEM_CHAIN_ID, NETWORKS_GOLOS_CHAIN_ID, NETWORKS_TEST_CHAIN_ID]
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Radiator
2
+ class ChainStatsApi < Api
3
+ def method_names
4
+ @method_names ||= [
5
+ :get_stats_for_time,
6
+ :get_stats_for_interval,
7
+ :get_lifetime_stats
8
+ ].freeze
9
+ end
10
+
11
+ def api_name
12
+ :chain_stats_api
13
+ end
14
+ end
15
+ end