# frozen_string_literal: true require('bigdecimal/util') # @author Hernani Rodrigues Vaz module Etht # classe para processar carteiras & transacoes normais e tokens class Carteiras # @return [Etherscan] API etherscan attr_reader :api # @return [Array] todos os dados bigquery attr_reader :dbq # @return [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho attr_reader :ops # @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 normais & tokens? # @return [Carteiras] API etherscan - processar transacoes normais e tokens def initialize(dad, pop) @api = Etherscan.new @dbq = dad @ops = pop end # @return [Array] todos os dados etherscan - saldos & transacoes def dadoses @dadoses ||= api.multi_address_balance(dbq[:wb].map { |c| c[:ax] }).map { |e| base_etherscan(e) } end # @return [Array] lista blocknumbers novos de transacoes normais def novobnt @novobnt ||= (dadoses.map { |e| e[:tx].map { |n| Integer(n['blockNumber']) } }.flatten - dbq[:nt].map { |t| t[:blocknumber] }).uniq end # @return [Array] lista blocknumbers novos de transacoes token def novobnk @novobnk ||= (dadoses.map { |e| e[:kx].map { |n| Integer(n['blockNumber']) } }.flatten - dbq[:nk].map { |t| t[:blocknumber] }).uniq end # @return [Array] lista transacoes normais novas def novaest @novaest ||= dadoses.map { |e| e[:tx].select { |s| novobnt.include?(Integer(s['blockNumber'])) } }.flatten.uniq end # @return [Array] lista transacoes tokan novas def novaesk @novaesk ||= dadoses.map { |e| e[:kx].select { |s| novobnk.include?(Integer(s['blockNumber'])) } }.flatten.uniq end # @return [Array] totdos dados juntos bigquery & etherscan def dadosjn @dadosjn ||= dbq[:wb].map { |b| bigquery_etherscan(b, dadoses.select { |s| b[:ax] == s[:ax] }.first) } end # @return [Array] lista ordenada transacoes normais novas def sortest novaest.sort { |a, b| Integer(a['blockNumber']) <=> Integer(b['blockNumber']) } end # @return [Array] lista ordenada transacoes tokan novas def sortesk novaesk.sort { |a, b| Integer(a['blockNumber']) <=> Integer(b['blockNumber']) } end # @return [Array] lista ordenada transacoes normais & tokan novas def totalha (novaest + novaesk).sort { |a, b| Integer(a['blockNumber']) <=> Integer(b['blockNumber']) } end # @param [Hash] hes dados etherscan # @return [Hash] dados etherscan - address, saldo & transacoes def base_etherscan(hes) { ax: hes['account'], sl: (hes['balance'].to_d / 10**18).round(10), tx: etherscan_tx(hes['account']), kx: etherscan_kx(hes['account']) } end # @param [Hash] hbq dados bigquery # @param [Hash] hes dados etherscan # @return [Hash] dados juntos bigquery & etherscan def bigquery_etherscan(hbq, hes) { id: hbq[:id], ax: hbq[:ax], bs: hbq[:sl], bt: dbq[:nt].select { |t| t[:iax] == hbq[:ax] }, bk: dbq[:nk].select { |t| t[:iax] == hbq[:ax] }, es: hes[:sl], et: hes[:tx], ek: hes[:kx] } end # @param [String] add endereco da carteira # @return [Array] lista transacoes normais ligadas a uma carteira - sem elementos irrelevantes def etherscan_tx(add) api.normal_tx(add).map do |e| e.delete('cumulativeGasUsed') e.delete('confirmations') e end end # @param (see etherscan_tx) # @return [Array] lista transacoes token ligadas a uma carteira - sem elementos irrelevantes def etherscan_kx(add) api.token_tx(add).map do |e| e.delete('cumulativeGasUsed') e.delete('confirmations') e end end # @return [Boolean] carteira tem transacoes novas(sim=NOK, nao=OK)? def ok?(hjn) hjn[:bs] == hjn[:es] && hjn[:bt].count == hjn[:et].count && hjn[:bk].count == hjn[:ek].count end end end