rubybear 0.0.2
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/Gemfile +3 -0
- data/Gemfile.lock +77 -0
- data/LICENSE +41 -0
- data/README.md +559 -0
- data/Rakefile +140 -0
- data/gource.sh +8 -0
- data/images/Anthony Martin.png +0 -0
- data/images/Marvin Hofmann.jpg +0 -0
- data/images/Marvin Hofmann.png +0 -0
- data/lib/bears.rb +17 -0
- data/lib/rubybear.rb +45 -0
- data/lib/rubybear/account_by_key_api.rb +7 -0
- data/lib/rubybear/account_history_api.rb +15 -0
- data/lib/rubybear/api.rb +907 -0
- data/lib/rubybear/base_error.rb +23 -0
- data/lib/rubybear/block_api.rb +14 -0
- data/lib/rubybear/broadcast_operations.json +500 -0
- data/lib/rubybear/chain.rb +299 -0
- data/lib/rubybear/chain_config.rb +22 -0
- data/lib/rubybear/chain_stats_api.rb +15 -0
- data/lib/rubybear/condenser_api.rb +99 -0
- data/lib/rubybear/database_api.rb +5 -0
- data/lib/rubybear/error_parser.rb +228 -0
- data/lib/rubybear/follow_api.rb +7 -0
- data/lib/rubybear/logger.rb +20 -0
- data/lib/rubybear/market_history_api.rb +19 -0
- data/lib/rubybear/methods.json +498 -0
- data/lib/rubybear/mixins/acts_as_poster.rb +124 -0
- data/lib/rubybear/mixins/acts_as_voter.rb +50 -0
- data/lib/rubybear/mixins/acts_as_wallet.rb +67 -0
- data/lib/rubybear/network_broadcast_api.rb +7 -0
- data/lib/rubybear/operation.rb +101 -0
- data/lib/rubybear/operation_ids.rb +98 -0
- data/lib/rubybear/operation_types.rb +139 -0
- data/lib/rubybear/stream.rb +527 -0
- data/lib/rubybear/tag_api.rb +33 -0
- data/lib/rubybear/transaction.rb +306 -0
- data/lib/rubybear/type/amount.rb +57 -0
- data/lib/rubybear/type/array.rb +17 -0
- data/lib/rubybear/type/beneficiaries.rb +29 -0
- data/lib/rubybear/type/future.rb +18 -0
- data/lib/rubybear/type/hash.rb +17 -0
- data/lib/rubybear/type/permission.rb +19 -0
- data/lib/rubybear/type/point_in_time.rb +19 -0
- data/lib/rubybear/type/price.rb +25 -0
- data/lib/rubybear/type/public_key.rb +18 -0
- data/lib/rubybear/type/serializer.rb +12 -0
- data/lib/rubybear/type/u_int16.rb +19 -0
- data/lib/rubybear/type/u_int32.rb +19 -0
- data/lib/rubybear/utils.rb +170 -0
- data/lib/rubybear/version.rb +4 -0
- data/rubybear.gemspec +40 -0
- metadata +412 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
module Rubybear
|
2
|
+
module Mixins
|
3
|
+
module ActsAsPoster
|
4
|
+
# Creates a post operation.
|
5
|
+
#
|
6
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
7
|
+
# options = {
|
8
|
+
# title: 'This is my fancy post title.',
|
9
|
+
# body: 'This is my fancy post body.',
|
10
|
+
# tags: %w(thess are my fancy tags)
|
11
|
+
# }
|
12
|
+
# bears.post(options)
|
13
|
+
# bears.broadcast!
|
14
|
+
#
|
15
|
+
# @param options [::Hash] options
|
16
|
+
# @option options [String] :title Title of the post.
|
17
|
+
# @option options [String] :body Body of the post.
|
18
|
+
# @option options [::Array<String>] :tags Tags of the post.
|
19
|
+
# @option options [String] :permlink (automatic) Permlink of the post, defaults to formatted title.
|
20
|
+
# @option options [String] :parent_permlink (automatic) Parent permlink of the post, defaults to first tag.
|
21
|
+
# @option options [String] :parent_author (optional) Parent author of the post (only used if reply).
|
22
|
+
# @option options [String] :max_accepted_payout (1000000.000 BSD) Maximum accepted payout, set to '0.000 BSD' to deline payout
|
23
|
+
# @option options [Integer] :percent_bears_dollars (5000) Percent BEARS Dollars is used to set 50/50 or 100% BEARS Power
|
24
|
+
# @option options [Integer] :allow_votes (true) Allow votes for this post.
|
25
|
+
# @option options [Integer] :allow_curation_rewards (true) Allow curation rewards for this post.
|
26
|
+
def post(options = {})
|
27
|
+
tags = [options[:tags] || []].flatten
|
28
|
+
title = options[:title].to_s
|
29
|
+
permlink = options[:permlink] || title.downcase.gsub(/[^a-z0-9\-]+/, '-')
|
30
|
+
parent_permlink = options[:parent_permlink] || tags[0]
|
31
|
+
|
32
|
+
raise ChainError, 'At least one tag is required or set the parent_permlink directy.' if parent_permlink.nil?
|
33
|
+
|
34
|
+
body = options[:body]
|
35
|
+
parent_author = options[:parent_author] || ''
|
36
|
+
max_accepted_payout = options[:max_accepted_payout] || default_max_acepted_payout
|
37
|
+
percent_bears_dollars = options[:percent_bears_dollars]
|
38
|
+
allow_votes = options[:allow_votes] || true
|
39
|
+
allow_curation_rewards = options[:allow_curation_rewards] || true
|
40
|
+
self_vote = options[:self_vote]
|
41
|
+
|
42
|
+
tags.insert(0, parent_permlink)
|
43
|
+
tags = tags.compact.uniq
|
44
|
+
|
45
|
+
metadata = {
|
46
|
+
app: Rubybear::AGENT_ID
|
47
|
+
}
|
48
|
+
metadata[:tags] = tags if tags.any?
|
49
|
+
|
50
|
+
@operations << {
|
51
|
+
type: :comment,
|
52
|
+
parent_permlink: parent_permlink,
|
53
|
+
author: account_name,
|
54
|
+
permlink: permlink,
|
55
|
+
title: title,
|
56
|
+
body: body,
|
57
|
+
json_metadata: metadata.to_json,
|
58
|
+
parent_author: parent_author
|
59
|
+
}
|
60
|
+
|
61
|
+
if (!!max_accepted_payout &&
|
62
|
+
max_accepted_payout != default_max_acepted_payout
|
63
|
+
) || !!percent_bears_dollars || !allow_votes || !allow_curation_rewards
|
64
|
+
@operations << {
|
65
|
+
type: :comment_options,
|
66
|
+
author: account_name,
|
67
|
+
permlink: permlink,
|
68
|
+
max_accepted_payout: max_accepted_payout,
|
69
|
+
percent_bears_dollars: percent_bears_dollars,
|
70
|
+
allow_votes: allow_votes,
|
71
|
+
allow_curation_rewards: allow_curation_rewards,
|
72
|
+
extensions: []
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
vote(self_vote, account_name, permlink) if !!self_vote
|
77
|
+
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
# Create a vote operation and broadcasts it right away.
|
82
|
+
#
|
83
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
84
|
+
# options = {
|
85
|
+
# title: 'This is my fancy post title.',
|
86
|
+
# body: 'This is my fancy post body.',
|
87
|
+
# tags: %w(thess are my fancy tags)
|
88
|
+
# }
|
89
|
+
# bears.post!(options)
|
90
|
+
#
|
91
|
+
# @see post
|
92
|
+
def post!(options = {}); post(options).broadcast!(true); end
|
93
|
+
|
94
|
+
# Create a delete_comment operation.
|
95
|
+
#
|
96
|
+
# Examples:
|
97
|
+
#
|
98
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
99
|
+
# bears.delete_comment('permlink')
|
100
|
+
# bears.broadcast!
|
101
|
+
#
|
102
|
+
# @param permlink
|
103
|
+
def delete_comment(permlink)
|
104
|
+
@operations << {
|
105
|
+
type: :delete_comment,
|
106
|
+
author: account_name,
|
107
|
+
permlink: permlink
|
108
|
+
}
|
109
|
+
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
# Create a delete_comment operation and broadcasts it right away.
|
114
|
+
#
|
115
|
+
# Examples:
|
116
|
+
#
|
117
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
118
|
+
# bears.delete_comment!('permlink')
|
119
|
+
#
|
120
|
+
# @see delete_comment
|
121
|
+
def delete_comment!(permlink); delete_comment(permlink).broadcast!(true); end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Rubybear
|
2
|
+
module Mixins
|
3
|
+
module ActsAsVoter
|
4
|
+
# Create a vote operation.
|
5
|
+
#
|
6
|
+
# Examples:
|
7
|
+
#
|
8
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
9
|
+
# bears.vote(10000, 'author', 'permlink')
|
10
|
+
# bears.broadcast!
|
11
|
+
#
|
12
|
+
# ... or ...
|
13
|
+
#
|
14
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
15
|
+
# bears.vote(10000, '@author/permlink')
|
16
|
+
# bears.broadcast!
|
17
|
+
#
|
18
|
+
# @param weight [Integer] value between -10000 and 10000.
|
19
|
+
# @param args [author, permlink || slug] pass either `author` and `permlink` or string containing both like `@author/permlink`.
|
20
|
+
def vote(weight, *args)
|
21
|
+
author, permlink = normalize_author_permlink(args)
|
22
|
+
|
23
|
+
@operations << {
|
24
|
+
type: :vote,
|
25
|
+
voter: account_name,
|
26
|
+
author: author,
|
27
|
+
permlink: permlink,
|
28
|
+
weight: weight
|
29
|
+
}
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create a vote operation and broadcasts it right away.
|
35
|
+
#
|
36
|
+
# Examples:
|
37
|
+
#
|
38
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
39
|
+
# bears.vote!(10000, 'author', 'permlink')
|
40
|
+
#
|
41
|
+
# ... or ...
|
42
|
+
#
|
43
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
44
|
+
# bears.vote!(10000, '@author/permlink')
|
45
|
+
#
|
46
|
+
# @see vote
|
47
|
+
def vote!(weight, *args); vote(weight, *args).broadcast!(true); end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Rubybear
|
2
|
+
module Mixins
|
3
|
+
module ActsAsWallet
|
4
|
+
# Create a claim_reward_balance operation.
|
5
|
+
#
|
6
|
+
# Examples:
|
7
|
+
#
|
8
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
9
|
+
# bears.claim_reward_balance(reward_bsd: '100.000 BSD')
|
10
|
+
# bears.broadcast!
|
11
|
+
#
|
12
|
+
# @param options [::Hash] options
|
13
|
+
# @option options [String] :reward_bears The amount of BEARS to claim, like: `100.000 BEARS`
|
14
|
+
# @option options [String] :reward_bsd The amount of BSD to claim, like: `100.000 BSD`
|
15
|
+
# @option options [String] :reward_coins The amount of COINS to claim, like: `100.000000 COINS`
|
16
|
+
def claim_reward_balance(options)
|
17
|
+
reward_bears = options[:reward_bears] || '0.000 BEARS'
|
18
|
+
reward_bsd = options[:reward_bsd] || '0.000 BSD'
|
19
|
+
reward_coins = options[:reward_coins] || '0.000000 COINS'
|
20
|
+
|
21
|
+
@operations << {
|
22
|
+
type: :claim_reward_balance,
|
23
|
+
account: account_name,
|
24
|
+
reward_bears: reward_bears,
|
25
|
+
reward_bsd: reward_bsd,
|
26
|
+
reward_coins: reward_coins
|
27
|
+
}
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
# Create a claim_reward_balance operation and broadcasts it right away.
|
33
|
+
#
|
34
|
+
# Examples:
|
35
|
+
#
|
36
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
37
|
+
# bears.claim_reward_balance!(reward_bsd: '100.000 BSD')
|
38
|
+
#
|
39
|
+
# @see claim_reward_balance
|
40
|
+
def claim_reward_balance!(permlink); claim_reward_balance(permlink).broadcast!(true); end
|
41
|
+
|
42
|
+
# Create a transfer operation.
|
43
|
+
#
|
44
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your active wif')
|
45
|
+
# bears.transfer(amount: '1.000 BSD', to: 'account name', memo: 'this is a memo')
|
46
|
+
# bears.broadcast!
|
47
|
+
#
|
48
|
+
# @param options [::Hash] options
|
49
|
+
# @option options [String] :amount The amount to transfer, like: `100.000 BEARS`
|
50
|
+
# @option options [String] :to The account receiving the transfer.
|
51
|
+
# @option options [String] :memo ('') The memo for the transfer.
|
52
|
+
def transfer(options = {})
|
53
|
+
@operations << options.merge(type: :transfer, from: account_name)
|
54
|
+
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Create a transfer operation and broadcasts it right away.
|
59
|
+
#
|
60
|
+
# bears = Rubybear::Chain.new(chain: :bears, account_name: 'your account name', wif: 'your wif')
|
61
|
+
# bears.transfer!(amount: '1.000 BSD', to: 'account name', memo: 'this is a memo')
|
62
|
+
#
|
63
|
+
# @see transfer
|
64
|
+
def transfer!(options = {}); transfer(options).broadcast!(true); end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Rubybear
|
2
|
+
class Operation
|
3
|
+
include OperationIds
|
4
|
+
include OperationTypes
|
5
|
+
include Utils
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
opt = options.dup
|
9
|
+
@type = opt.delete(:type)
|
10
|
+
|
11
|
+
opt.each do |k, v|
|
12
|
+
instance_variable_set("@#{k}", type(@type, k, v))
|
13
|
+
end
|
14
|
+
|
15
|
+
@use_condenser_namespace = if options.keys.include? :use_condenser_namespace
|
16
|
+
options.delete(:use_condenser_namespace)
|
17
|
+
else
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
unless Operation::known_operation_names.include? @type
|
22
|
+
raise OperationError, "Unsupported operation type: #{@type}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_bytes
|
27
|
+
bytes = [id(@type.to_sym)].pack('C')
|
28
|
+
|
29
|
+
Operation::param_names(@type.to_sym).each do |p|
|
30
|
+
next unless defined? p
|
31
|
+
|
32
|
+
v = instance_variable_get("@#{p}")
|
33
|
+
bytes += v.to_bytes and next if v.respond_to? :to_bytes
|
34
|
+
|
35
|
+
bytes += case v
|
36
|
+
when Symbol then pakStr(v.to_s)
|
37
|
+
when String then pakStr(v)
|
38
|
+
when Integer then paks(v)
|
39
|
+
when TrueClass then pakC(1)
|
40
|
+
when FalseClass then pakC(0)
|
41
|
+
when ::Array then pakArr(v)
|
42
|
+
when ::Hash then pakHash(v)
|
43
|
+
when NilClass then next
|
44
|
+
else
|
45
|
+
raise OperationError, "Unsupported type: #{v.class}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
bytes
|
50
|
+
end
|
51
|
+
|
52
|
+
def payload
|
53
|
+
params = {}
|
54
|
+
|
55
|
+
Operation::param_names(@type.to_sym).each do |p|
|
56
|
+
next unless defined? p
|
57
|
+
|
58
|
+
v = instance_variable_get("@#{p}")
|
59
|
+
next if v.nil?
|
60
|
+
next if v.class == Rubybear::Type::Future
|
61
|
+
|
62
|
+
params[p] = case v
|
63
|
+
when Rubybear::Type::Beneficiaries then [[0, v.to_h]]
|
64
|
+
when Rubybear::Type::Amount
|
65
|
+
if use_condenser_namespace?
|
66
|
+
v.to_s
|
67
|
+
else
|
68
|
+
v.to_a
|
69
|
+
end
|
70
|
+
else; v
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
[@type, params]
|
75
|
+
end
|
76
|
+
private
|
77
|
+
def self.broadcast_operations_json_path
|
78
|
+
@broadcast_operations_json_path ||= "#{File.dirname(__FILE__)}/broadcast_operations.json"
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.broadcast_operations
|
82
|
+
@broadcast_operations ||= JSON[File.read broadcast_operations_json_path]
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.known_operation_names
|
86
|
+
broadcast_operations.map { |op| op["operation"].to_sym }
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.param_names(type)
|
90
|
+
broadcast_operations.each do |op|
|
91
|
+
if op['operation'].to_sym == type.to_sym
|
92
|
+
return op['params'].map(&:to_sym)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def use_condenser_namespace?
|
98
|
+
@use_condenser_namespace
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Rubybear
|
2
|
+
module OperationIds
|
3
|
+
# These IDS are derrived from:
|
4
|
+
# https://github.com/bearshares/bears/blob/127a441fbac2f06804359968bda83b66e602c891/libraries/protocol/include/bears/protocol/operations.hpp
|
5
|
+
|
6
|
+
IDS = [
|
7
|
+
:vote_operation,
|
8
|
+
:comment_operation,
|
9
|
+
|
10
|
+
:transfer_operation,
|
11
|
+
:transfer_to_coining_operation,
|
12
|
+
:withdraw_coining_operation,
|
13
|
+
|
14
|
+
:limit_order_create_operation,
|
15
|
+
:limit_order_cancel_operation,
|
16
|
+
|
17
|
+
:feed_publish_operation,
|
18
|
+
:convert_operation,
|
19
|
+
|
20
|
+
:account_create_operation,
|
21
|
+
:account_update_operation,
|
22
|
+
|
23
|
+
:witness_update_operation,
|
24
|
+
:account_witness_vote_operation,
|
25
|
+
:account_witness_proxy_operation,
|
26
|
+
|
27
|
+
:pow_operation,
|
28
|
+
|
29
|
+
:custom_operation,
|
30
|
+
|
31
|
+
:report_over_production_operation,
|
32
|
+
|
33
|
+
:delete_comment_operation,
|
34
|
+
:custom_json_operation,
|
35
|
+
:comment_options_operation,
|
36
|
+
:set_withdraw_coining_route_operation,
|
37
|
+
:limit_order_create2_operation,
|
38
|
+
:claim_account_operation,
|
39
|
+
:create_claimed_account_operation,
|
40
|
+
:request_account_recovery_operation,
|
41
|
+
:recover_account_operation,
|
42
|
+
:change_recovery_account_operation,
|
43
|
+
:escrow_transfer_operation,
|
44
|
+
:escrow_dispute_operation,
|
45
|
+
:escrow_release_operation,
|
46
|
+
:pow2_operation,
|
47
|
+
:escrow_approve_operation,
|
48
|
+
:transfer_to_savings_operation,
|
49
|
+
:transfer_from_savings_operation,
|
50
|
+
:cancel_transfer_from_savings_operation,
|
51
|
+
:custom_binary_operation,
|
52
|
+
:decline_voting_rights_operation,
|
53
|
+
:reset_account_operation,
|
54
|
+
:set_reset_account_operation,
|
55
|
+
:claim_reward_balance_operation,
|
56
|
+
:delegate_coining_shares_operation,
|
57
|
+
:account_create_with_delegation_operation,
|
58
|
+
:witness_set_properties_operation,
|
59
|
+
|
60
|
+
# SMT operations
|
61
|
+
:claim_reward_balance2_operation,
|
62
|
+
|
63
|
+
:smt_setup_operation,
|
64
|
+
:smt_cap_reveal_operation,
|
65
|
+
:smt_refund_operation,
|
66
|
+
:smt_setup_emissions_operation,
|
67
|
+
:smt_set_setup_parameters_operation,
|
68
|
+
:smt_set_runtime_parameters_operation,
|
69
|
+
:smt_create_operation,
|
70
|
+
|
71
|
+
# virtual operations below this point
|
72
|
+
:fill_convert_request_operation,
|
73
|
+
:author_reward_operation,
|
74
|
+
:curation_reward_operation,
|
75
|
+
:comment_reward_operation,
|
76
|
+
:liquidity_reward_operation,
|
77
|
+
:interest_operation,
|
78
|
+
:fill_coining_withdraw_operation,
|
79
|
+
:fill_order_operation,
|
80
|
+
:shutdown_witness_operation,
|
81
|
+
:fill_transfer_from_savings_operation,
|
82
|
+
:hardfork_operation,
|
83
|
+
:comment_payout_update_operation,
|
84
|
+
:return_coining_delegation_operation,
|
85
|
+
:comment_benefactor_reward_operation,
|
86
|
+
:producer_reward_operation,
|
87
|
+
:clear_null_account_balance_operation
|
88
|
+
]
|
89
|
+
|
90
|
+
def id(op)
|
91
|
+
if op.to_s =~ /_operation$/
|
92
|
+
IDS.find_index op
|
93
|
+
else
|
94
|
+
IDS.find_index "#{op}_operation".to_sym
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|