steem-ruby 0.1.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 +7 -0
- data/.gitignore +54 -0
- data/CONTRIBUTING.md +79 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +73 -0
- data/LICENSE +22 -0
- data/README.md +77 -0
- data/Rakefile +115 -0
- data/gource.sh +6 -0
- data/images/Anthony Martin.png +0 -0
- data/lib/steem/api.rb +190 -0
- data/lib/steem/base_error.rb +151 -0
- data/lib/steem/block_api.rb +45 -0
- data/lib/steem/broadcast.rb +1056 -0
- data/lib/steem/chain_config.rb +36 -0
- data/lib/steem/formatter.rb +14 -0
- data/lib/steem/jsonrpc.rb +98 -0
- data/lib/steem/mixins/retriable.rb +56 -0
- data/lib/steem/rpc/base_client.rb +154 -0
- data/lib/steem/rpc/thread_safe_client.rb +23 -0
- data/lib/steem/transaction_builder.rb +266 -0
- data/lib/steem/type/amount.rb +61 -0
- data/lib/steem/type/base_type.rb +10 -0
- data/lib/steem/utils.rb +17 -0
- data/lib/steem/version.rb +4 -0
- data/lib/steem.rb +35 -0
- data/steem-ruby.gemspec +37 -0
- metadata +390 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
module Steem
|
2
|
+
class BaseError < StandardError
|
3
|
+
def initialize(error, cause = nil)
|
4
|
+
@error = error
|
5
|
+
@cause = cause
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
if !!@cause
|
10
|
+
JSON[error: @error, cause: @cause] rescue {error: @error, cause: @cause}.to_s
|
11
|
+
else
|
12
|
+
JSON[@error] rescue @error.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.build_error(error, context)
|
17
|
+
if error.message == 'Unable to acquire database lock'
|
18
|
+
raise Steem::RemoteNodeError, error.message, JSON.pretty_generate(error)
|
19
|
+
end
|
20
|
+
|
21
|
+
if error.message.include? 'Internal Error'
|
22
|
+
raise Steem::RemoteNodeError.new, error.message, JSON.pretty_generate(error)
|
23
|
+
end
|
24
|
+
|
25
|
+
if error.message.include? 'plugin not enabled'
|
26
|
+
raise Steem::RemoteNodeError, error.message, JSON.pretty_generate(error)
|
27
|
+
end
|
28
|
+
|
29
|
+
if error.message.include? 'argument'
|
30
|
+
raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
31
|
+
end
|
32
|
+
|
33
|
+
if error.message.start_with? 'Bad Cast:'
|
34
|
+
raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
35
|
+
end
|
36
|
+
|
37
|
+
if error.message.include? 'prefix_len'
|
38
|
+
raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
39
|
+
end
|
40
|
+
|
41
|
+
if error.message.include? 'Parse Error'
|
42
|
+
raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
43
|
+
end
|
44
|
+
|
45
|
+
if error.message.include? 'unknown key'
|
46
|
+
raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
47
|
+
end
|
48
|
+
|
49
|
+
if error.message.include? 'A transaction must have at least one operation'
|
50
|
+
raise Steem::EmptyTransactionError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
51
|
+
end
|
52
|
+
|
53
|
+
if error.message.include? 'transaction expiration exception'
|
54
|
+
raise Steem::TransactionExpiredError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
55
|
+
end
|
56
|
+
|
57
|
+
if error.message.include? 'Duplicate transaction check failed'
|
58
|
+
raise Steem::DuplicateTransactionError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
59
|
+
end
|
60
|
+
|
61
|
+
if error.message.include? 'signature is not canonical'
|
62
|
+
raise Steem::NonCanonicalSignatureError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
63
|
+
end
|
64
|
+
|
65
|
+
if error.message.include? 'attempting to push a block that is too old'
|
66
|
+
raise Steem::BlockTooOldError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
67
|
+
end
|
68
|
+
|
69
|
+
if error.message.include? 'irrelevant signature'
|
70
|
+
raise Steem::IrrelevantSignatureError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
71
|
+
end
|
72
|
+
|
73
|
+
if error.message.include? 'missing required posting authority'
|
74
|
+
raise Steem::MissingPostingAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
75
|
+
end
|
76
|
+
|
77
|
+
if error.message.include? 'missing required active authority'
|
78
|
+
raise Steem::MissingActiveAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
79
|
+
end
|
80
|
+
|
81
|
+
if error.message.include? 'missing required owner authority'
|
82
|
+
raise Steem::MissingOwnerAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
83
|
+
end
|
84
|
+
|
85
|
+
if error.message.include? 'missing required other authority'
|
86
|
+
raise Steem::MissingOtherAuthorityError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
87
|
+
end
|
88
|
+
|
89
|
+
if error.message.include? 'is_valid_account_name'
|
90
|
+
raise Steem::InvalidAccountError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
91
|
+
end
|
92
|
+
|
93
|
+
if error.message.include? 'Invalid operation name'
|
94
|
+
raise Steem::UnknownOperationError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
95
|
+
end
|
96
|
+
|
97
|
+
if error.message.include? 'Author not found'
|
98
|
+
raise Steem::AuthorNotFoundError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
99
|
+
end
|
100
|
+
|
101
|
+
if error.message.include? ' != fc::time_point_sec::maximum()'
|
102
|
+
raise Steem::ReachedMaximumTimeError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
103
|
+
end
|
104
|
+
|
105
|
+
if error.message.include? 'Cannot transfer a negative amount (aka: stealing)'
|
106
|
+
raise Steem::TheftError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
107
|
+
end
|
108
|
+
|
109
|
+
if error.message.include? 'Must transfer a nonzero amount'
|
110
|
+
raise Steem::NonZeroRequiredError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
111
|
+
end
|
112
|
+
|
113
|
+
if error.message.include? 'is_asset_type'
|
114
|
+
raise Steem::UnexpectedAssetError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
115
|
+
end
|
116
|
+
|
117
|
+
if error.message.include? 'unable to convert ISO-formatted string to fc::time_point_sec'
|
118
|
+
raise Steem::ArgumentError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
119
|
+
end
|
120
|
+
|
121
|
+
puts JSON.pretty_generate(error) if ENV['DEBUG']
|
122
|
+
raise UnknownError, "#{context}: #{error.message}", JSON.pretty_generate(error)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class UnsupportedChainError < BaseError; end
|
127
|
+
class ArgumentError < BaseError; end
|
128
|
+
class RemoteNodeError < BaseError; end
|
129
|
+
class TypeError < BaseError; end
|
130
|
+
class EmptyTransactionError < BaseError; end
|
131
|
+
class TransactionExpiredError < BaseError; end
|
132
|
+
class DuplicateTransactionError < BaseError; end
|
133
|
+
class NonCanonicalSignatureError < BaseError; end
|
134
|
+
class BlockTooOldError < BaseError; end
|
135
|
+
class IrrelevantSignatureError < BaseError; end
|
136
|
+
class MissingPostingAuthorityError < BaseError; end
|
137
|
+
class MissingActiveAuthorityError < BaseError; end
|
138
|
+
class MissingOwnerAuthorityError < BaseError; end
|
139
|
+
class MissingOtherAuthorityError < BaseError; end
|
140
|
+
class InvalidAccountError < BaseError; end
|
141
|
+
class AuthorNotFoundError < BaseError; end
|
142
|
+
class ReachedMaximumTimeError < BaseError; end
|
143
|
+
class TheftError < BaseError; end
|
144
|
+
class NonZeroRequiredError < BaseError; end
|
145
|
+
class UnexpectedAssetError < BaseError; end
|
146
|
+
class IncorrectRequestIdError < BaseError; end
|
147
|
+
class IncorrectResponseIdError < BaseError; end
|
148
|
+
class UnknownApiError < BaseError; end
|
149
|
+
class UnknownOperationError < BaseError; end
|
150
|
+
class UnknownError < BaseError; end
|
151
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Steem
|
2
|
+
# {BlockApi} is used to query values related to the block plugin. It can also
|
3
|
+
# be used to access a range of multiple blocks by using
|
4
|
+
# {http://www.jsonrpc.org/specification#batch JSON-RPC 2.0 batch} requests.
|
5
|
+
#
|
6
|
+
# Also see: {https://developers.steem.io/apidefinitions/block-api Block API Definitions}
|
7
|
+
class BlockApi < Api
|
8
|
+
MAX_RANGE_SIZE = 3000
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
self.class.api_name = :block_api
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
# Uses a batched requst on a range of blocks.
|
16
|
+
#
|
17
|
+
# @param options [Hash] The attributes to get a block range with.
|
18
|
+
# @option options [Range] :block_range starting on one block number and ending on an higher block number.
|
19
|
+
def get_blocks(options = {block_range: [0..0]}, &block)
|
20
|
+
block_range = options[:block_range] || [0..0]
|
21
|
+
|
22
|
+
if block_range.size > MAX_RANGE_SIZE
|
23
|
+
raise Steem::ArgumentError, "Too many blocks requested: #{block_range.size}; maximum request size: #{MAX_RANGE_SIZE}."
|
24
|
+
end
|
25
|
+
|
26
|
+
request_body = []
|
27
|
+
|
28
|
+
for i in block_range do
|
29
|
+
@rpc_client.put(self.class.api_name, :get_block, block_num: i, request_body: request_body)
|
30
|
+
end
|
31
|
+
|
32
|
+
if !!block
|
33
|
+
@rpc_client.rpc_post(nil, nil, request_body: request_body) do |result, error, id|
|
34
|
+
yield result.nil? ? nil : result.block, error, id
|
35
|
+
end
|
36
|
+
else
|
37
|
+
blocks = []
|
38
|
+
|
39
|
+
@rpc_client.rpc_post(nil, nil, request_body: request_body) do |result, error, id|
|
40
|
+
blocks << result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|