Class: Radiator::Chain

Inherits:
Object
  • Object
show all
Includes:
Mixins::ActsAsPoster, Mixins::ActsAsVoter, Mixins::ActsAsWallet
Defined in:
lib/radiator/chain.rb

Overview

Examples …

To vote on a post/comment:

steem = Radiator::Chain.new(chain: :steem, account_name: 'your account name', wif: 'your wif')
steem.vote!(10000, 'author', 'post-or-comment-permlink')

To post and vote in the same transaction:

steem = Radiator::Chain.new(chain: :steem, account_name: 'your account name', wif: 'your wif')
steem.post!(title: 'title of my post', body: 'body of my post', tags: ['tag'], self_upvote: 10000)

To post and vote with declined payout:

steem = Radiator::Chain.new(chain: :steem, account_name: 'your account name', wif: 'your wif')

options = {
  title: 'title of my post',
  body: 'body of my post',
  tags: ['tag'],
  self_upvote: 10000,
  percent_hbd: 0
}

steem.post!(options)

Constant Summary collapse

VALID_OPTIONS =
%w(
  chain account_name wif url failover_urls
).map(&:to_sym)

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixins::ActsAsWallet

#claim_reward_balance, #claim_reward_balance!, #transfer, #transfer!

Methods included from Mixins::ActsAsVoter

#vote, #vote!

Methods included from Mixins::ActsAsPoster

#delete_comment, #delete_comment!, #post, #post!

Constructor Details

#initialize(options = {}) ⇒ Chain

Returns a new instance of Chain.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/radiator/chain.rb', line 51

def initialize(options = {})
  options = options.dup
  options.each do |k, v|
    k = k.to_sym
    if VALID_OPTIONS.include?(k.to_sym)
      options.delete(k)
      send("#{k}=", v)
    end
  end
  
  @account_name ||= ENV['ACCOUNT_NAME']
  @wif ||= ENV['WIF']
  
  reset
end

Class Method Details

.parse_slug(*args) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/radiator/chain.rb', line 38

def self.parse_slug(*args)
  args = [args].flatten
  
  if args.size == 1
    case args[0]
    when String then split_slug(args[0])
    when ::Hash then [args[0]['author'], args[0]['permlink']]
    end
  else
    args
  end
end

Instance Method Details

#base_per_debtObject

Returns the current base (e.g. STEEM) price in the debt asset (e.g SBD).



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/radiator/chain.rb', line 156

def base_per_debt
  api.get_feed_history do |feed_history|
    current_median_history = feed_history.current_median_history
    base = current_median_history.base
    base = base.split(' ').first.to_f
    quote = current_median_history.quote
    quote = quote.split(' ').first.to_f
    
    (base / quote) * base_per_mvest
  end
end

#base_per_mvestObject

Returns the current base (e.g. STEEM) price in the vest asset (e.g. VESTS).



147
148
149
150
151
152
# File 'lib/radiator/chain.rb', line 147

def base_per_mvest
  total_vesting_fund_steem = properties.total_vesting_fund_steem.to_f
  total_vesting_shares_mvest = properties.total_vesting_shares.to_f / 1e6

  total_vesting_fund_steem / total_vesting_shares_mvest
end

#block_timeObject



140
141
142
# File 'lib/radiator/chain.rb', line 140

def block_time
  Time.parse(properties.time + 'Z')
end

#broadcast!(auto_reset = false) ⇒ Object

Broadcast queued operations.

Parameters:

  • auto_reset (boolean) (defaults to: false)

    clears operations no matter what, even if there’s an error.

Raises:



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/radiator/chain.rb', line 235

def broadcast!(auto_reset = false)
  raise ChainError, "Required option: chain" if @chain.nil?
  raise ChainError, "Required option: account_name, wif" if @account_name.nil? || @wif.nil?
  
  begin
    transaction = Radiator::Transaction.new(build_options)
    transaction.operations = @operations
    response = transaction.process(true)
  rescue => e
    reset if auto_reset
    raise e
  end
  
  if !!response.result
    reset
    response
  else
    reset if auto_reset
    ErrorParser.new(response)
  end
end

#find_account(account_name) ⇒ ::Hash

Find a specific account by name.

Example:

steem = Radiator::Chain.new(chain: :steem)
ned = steem.('ned')
vesting_shares = ned.vesting_shares

Parameters:

  • account_name (String)

    Name of the account to find.

Returns:

  • (::Hash)


91
92
93
94
95
96
97
# File 'lib/radiator/chain.rb', line 91

def ()
  api.get_accounts([]) do |accounts, err|
    raise ChainError, ErrorParser.new(err) if !!err
    
    accounts[0]
  end
end

#find_block(block_number) ⇒ ::Hash

Find a specific block by block number.

Example:

steem = Radiator::Chain.new(chain: :steem)
block = steem.find_block(12345678)
transactions = block.transactions

Parameters:

  • block_number (Fixnum)

Returns:

  • (::Hash)


77
78
79
# File 'lib/radiator/chain.rb', line 77

def find_block(block_number)
  api.get_blocks(block_number).first
end

#find_comment(*args) ⇒ ::Hash

Find a specific comment by author and permlink or slug.

Example:

steem = Radiator::Chain.new(chain: :steem)
comment = steem.find_comment('inertia', 'kinda-spooky') # by account, permlink
active_votes = comment.active_votes

… or …

comment = steem.find_comment('@inertia/kinda-spooky') # by slug

Parameters:

  • args (String || ::Array<String>)

    Slug or author, permlink of comment.

Returns:

  • (::Hash)


113
114
115
116
117
118
119
120
121
# File 'lib/radiator/chain.rb', line 113

def find_comment(*args)
  author, permlink = Chain.parse_slug(args)
  
  api.get_content(author, permlink) do |comment, err|
    raise ChainError, ErrorParser.new(err) if !!err
    
    comment unless comment.id == 0
  end
end

#followed_by(account_name) ⇒ ::Array<String>

List of accounts followed by account.

Parameters:

  • account_name

    String Name of the account.

Returns:

  • (::Array<String>)


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/radiator/chain.rb', line 172

def followed_by()
  return [] if .nil?
  
  followers = []
  count = -1

  until count == followers.size
    count = followers.size
    follow_api.get_followers(account: , start: followers.last, type: 'blog', limit: 1000) do |follows, err|
      raise ChainError, ErrorParser.new(err) if !!err
      
      followers += follows.map(&:follower)
      followers = followers.uniq
    end
  end
  
  followers
end

#following(account_name) ⇒ ::Array<String>

List of accounts following account.

Parameters:

  • account_name

    String Name of the account.

Returns:

  • (::Array<String>)


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/radiator/chain.rb', line 195

def following()
  return [] if .nil?
  
  following = []
  count = -1

  until count == following.size
    count = following.size
    follow_api.get_following(account: , start: following.last, type: 'blog', limit: 100) do |follows, err|
      raise ChainError, ErrorParser.new(err) if !!err
      
      following += follows.map(&:following)
      following = following.uniq
    end
  end

  following
end

#propertiesObject

Current dynamic global properties, cached for 3 seconds. This is useful for reading properties without worrying about actually fetching it over rpc more than needed.



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/radiator/chain.rb', line 126

def properties
  @properties ||= nil
  
  if !!@properties && Time.now.utc - Time.parse(@properties.time + 'Z') > 3
    @properties = nil
  end
  
  return @properties if !!@properties
  
  api.get_dynamic_global_properties do |properties|
    @properties = properties
  end
end

#resetObject

Clears out all properties and operations.



225
226
227
228
229
230
# File 'lib/radiator/chain.rb', line 225

def reset
  reset_properties
  reset_operations
  
  @api = @block_api = @follow_api = nil
end

#reset_operationsObject

Clears out queued operations.



220
221
222
# File 'lib/radiator/chain.rb', line 220

def reset_operations
  @operations = []
end

#reset_propertiesObject

Clears out queued properties.



215
216
217
# File 'lib/radiator/chain.rb', line 215

def reset_properties
  @properties = nil
end