# frozen_string_literal: true require('bigdecimal/util') # @author Hernani Rodrigues Vaz module Eost # classe para processar carteiras & transacoes class Carteiras # @return [Eosscan] API eosscan attr_reader :api # @return [Array] todos os dados bigquery attr_reader :dbq # @return [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho attr_reader :ops # @return [Array] lista blocknumbers transacoes no bigquery - condicionados por opcoes iniciais attr_reader :abn # @param [Hash] dad todos os dados bigquery # @param [Thor::CoreExt::HashWithIndifferentAccess] pop opcoes trabalho # @option pop [Hash] :h ({}) configuracao dias ajuste reposicionamento temporal # @option pop [Boolean] :v (false) mostra dados transacoes? # @option pop [Boolean] :t (false) mostra transacoes todas ou somente novas? # @return [Carteiras] API eosscan - processar transacoes def initialize(dad, pop) @api = Eosscan.new @dbq = dad @ops = pop @abn = (ops[:t] ? [] : dbq[:nt].map { |t| t[:blocknumber] }) end # @return [Array] todos os dados eosscan - saldos & transacoes def des @des ||= dbq[:wb].map { |e| base_eosscan(e) } end # @return [Array] todos os dados juntos bigquery & eosscan def djn @djn ||= dbq[:wb].map { |b| bigquery_eosscan(b, des.select { |s| b[:ax] == s[:ax] }.first) } end # @return [Array] lista blocknumbers de transacoes novas def bnn @bnn ||= (des.map { |e| e[:tx].map { |n| Integer(n['block_num']) } }.flatten - abn) end # @return [Array] lista transacoes novas def novas @novas ||= des.map { |e| e[:tx].select { |s| bnn.include?(Integer(s['block_num'])) } }.flatten.uniq end # @return [Array] lista ordenada transacoes novas def novas_sort novas.sort { |a, b| Integer(a['block_num']) <=> Integer(b['block_num']) } end # @param [Hash] hwb wallet bigquery eos # @return [Hash] dados eosscan - address, saldo & transacoes def base_eosscan(hwb) { ax: hwb[:ax], sl: eosscan_sl(hwb[:ax]).inject(:+), tx: eosscan_tx(hwb[:ax]) } end # @param (see bigquery_eosscan) # @return [Hash] lista blocknumbers novos & carteira ok? def novas_ok(hwb, hes) # quando todas as transacoes obtidas da api vao ser inseridas, # entao podem ficar transacoes por inserir - api consegue apenas um maximo de 100 transacoes n = hes[:tx].map { |v| Integer(v['block_num']) } - abn { nn: n, ok: hwb[:sl] == hes[:sl] && n.count < hes[:tx].count } end # @param hwb (see base_eosscan) # @param [Hash] hes dados eosscan # @return [Hash] dados juntos bigquery & eosscan def bigquery_eosscan(hwb, hes) { id: hwb[:id], ax: hwb[:ax], bs: hwb[:sl], bt: dbq[:nt].select { |t| t[:iax] == hwb[:ax] }, es: hes[:sl], et: hes[:tx] }.merge(novas_ok(hwb, hes)) end # @param [String] add endereco carteira EOS # @return [Array] lista recursos - liquido, net, spu def eosscan_sl(add) v = api.chain_get_account(account_name: add) [ v['core_liquid_balance'].to_d, v['total_resources']['net_weight'].to_d, v['total_resources']['cpu_weight'].to_d ] end # @param (see eosscan_sl) # @return [Array] lista ultimas 100 transacoes ligadas a uma carteira - sem elementos irrelevantes def eosscan_tx(add) api.history_get_actions(account_name: add, offset: -100)['actions'].map do |e| e.delete('global_action_seq') e end end end end