lib/etht/etherscan.rb in etht-0.1.4 vs lib/etht/etherscan.rb in etht-0.1.5
- old
+ new
@@ -1,177 +1,129 @@
# frozen_string_literal: true
-require 'faraday'
-require 'json'
+require('faraday')
+require('json')
# @author Hernani Rodrigues Vaz
module Etht
- # class Config
- class Config
- attr_accessor :key, :secret, :url, :raise_exceptions
- attr_writer :logger
+ # classe para tratar pedidos etherscan com chave API
+ class Etherscan
+ attr_reader :key, :url
- def logger
- @logger ||= Logger.new(STDERR)
+ # @param [String] :key apikey a juntar aos pedidos HTTP url:
+ # @param [String] :url base URL to use as a prefix for all requests
+ # @return [Etherscan] API etherscan base
+ def initialize(key: ENV['ETHERSCAN_API_KEY'], url: 'https://api.etherscan.io/')
+ @key = key
+ @url = url
end
- end
- # class Api
- class Api
- attr_reader :connection
-
- def initialize(params = {})
- @connection = Etht::Client.new(params)
+ # @return [<Symbol>] adapter for the connection - default :net_http
+ def adapter
+ @adapter ||= Faraday.default_adapter
end
- def get(params)
- response = connection.get(params)
- response['result']
+ # manage the default properties and the middleware stack for fulfilling an HTTP request
+ #
+ # @return [<Faraday::Connection>] connection object with an URL & adapter
+ def conn
+ @conn ||=
+ Faraday.new(url: url) do |c|
+ c.request(:url_encoded)
+ c.adapter(adapter)
+ end
end
- end
- # class Client
- class Client
- URL = 'https://api.etherscan.io/'
- HEADERS = { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }.freeze
+ # @return [<Hash>] resultado json do GET HTTP request
+ def get(**ars)
+ r =
+ conn.get('api') do |o|
+ o.headers = { content_type: 'application/json', accept: 'application/json', user_agent: 'etherscan;ruby' }
+ o.params = ars.merge({ apikey: key })
+ end
+ raise(Etht::Erro, r) if r.status != 200
- attr_reader :key, :url, :user_agent, :headers, :raise_exceptions
- attr_writer :adapter, :conn
-
- def initialize(params = {})
- @key = params.fetch(:key, Etht.config.key)
- @url = params.fetch(:url, Etht.config.url || URL)
- @adapter = params.fetch(:adapter, adapter)
- @conn = params.fetch(:conn, conn)
- @user_agent = params.fetch(:user_agent, "etherscan/#{Etht::VERSION};ruby")
- @headers = HEADERS.merge('User-Agent' => @user_agent)
- @raise_exceptions = params.fetch(:raise_exceptions, Etht.config.raise_exceptions || true)
- yield self if block_given?
+ JSON(r.body)['result']
end
- def get(params = {})
- endpoint = 'api'
- merged_params = params.merge({ apikey: key })
- response = conn.get(endpoint) do |req|
- req.headers = headers
- req.params = merged_params
- end
- raise Etht::Exception, response if raise_exceptions? && response.status != 200
+ # get ether balance for a single address
+ #
+ # @param [String] add address for balance
+ # @return [<String>] devolve saldo
+ def address_balance(add)
+ raise(Etht::Erro, 'address must be defined') if add.nil?
- JSON(response.body)
+ get(module: 'account', action: 'balance', address: add, tag: 'latest')
end
- def conn
- @conn ||= Faraday.new(url: @url) do |conn|
- conn.request :url_encoded
- conn.adapter adapter
- end
- end
+ # get ether balance for multiple addresses
+ #
+ # @param [String] ads lista de addresses (max 20)
+ # @return [Array<Hash>] devolve lista com contas & saldo
+ def multi_address_balance(ads)
+ raise(Etht::Erro, 'up to 20 accounts in a single batch') if ads.size > 20
- def adapter
- @adapter ||= Faraday.default_adapter
+ get(module: 'account', action: 'balancemulti', address: ads.join(','), tag: 'latest')
end
- def raise_exceptions?
- @raise_exceptions
- end
- end
+ # get ERC20-token account balance
+ #
+ # @param add (see address_balance)
+ # @param [String] cdd token contract address
+ # @return (see address_balance)
+ def token_balance(add, cdd)
+ raise(Etht::Erro, 'contract or address must be defined') if (cdd || add).nil?
- # class Accounts < Etht::Api
- class Accounts < Api
- def address_balance(address)
- params = {
- module: 'account', action: 'balance',
- address: address, tag: 'latest'
- }
- get(params)
+ get(module: 'account', action: 'tokenbalance', address: add, contractaddress: cdd)
end
- def multi_address_balance(addresses)
- raise Etht::Exception, 'up to 20 accounts in a single batch' if addresses.size > 20
+ # get a list of normal transactions by address
+ #
+ # @param [String] add address for transactions
+ # @param [Hash] ars opcoes trabalho
+ # @option ars [String] :start_block starting blockNo to retrieve results
+ # @option ars [String] :end_block ending blockNo to retrieve results
+ # @option ars [String] :sort asc -> ascending order, desc -> descending order
+ # @option ars [String] :page to get paginated results
+ # @option ars [String] :offset max records to return
+ # @return [Array<Hash>] devolve ate max 10000 das ultimas transacoes
+ def normal_tx(add, **ars)
+ raise(Etht::Erro, 'address must be defined') if add.nil?
- params = {
- module: 'account', action: 'balancemulti',
- address: addresses.join(','), tag: 'latest'
- }
- get(params)
+ transcations('txlist', add, nil, **ars)
end
- # Get a list of 'Normal' Transactions By Address
- # if page is not defined Returns up to 10000 last transactions
- # Available args: start_block, end_block, sort, page, offset
- # @param sort 'asc' -> ascending order, 'des' -> descending order
- # @param start_block starting blockNo to retrieve results
- # @param end_block ending blockNo to retrieve results
- # @param page Paginated result <page number>
- # @param offset max records to return
- def normal_transactions(address, args = {})
- action = 'txlist'
- transcations(action, address, nil, args)
- end
+ # get a list of ERC20 - token transfer events
+ #
+ # @param add (see normal_tx)
+ # @param [String] cdd token address (nil to get a list of all ERC20 transactions)
+ # @param ars (see normal_tx)
+ # @option ars (see normal_tx)
+ # @return (see normal_tx)
+ def token_tx(add, cdd = nil, **ars)
+ raise(Etht::Erro, 'contract or address must be defined') if (cdd || add).nil?
- # Get a list of 'Internal' Transactions By Address
- # Available args: start_block, end_block, sort, page, offset
- def internal_transactions(address, args = {})
- action = 'txlistinternal'
- transcations(action, address, nil, args)
+ transcations('tokentx', add, cdd, **ars)
end
- # Get a list of "ERC20 - Token Transfer Events"
- # @param contract_address Token address (set nil to get a list of all ERC20 transactions)
- # @param address Address for ERC20 transactions (optional)
- # Available args: start_block, end_block, sort, page, offset
- def token_transactions(contract_address, address = nil, args = {})
- raise Etht::Exception, 'contract or address must be defined' if (contract_address || address).nil?
-
- action = 'tokentx'
- transcations(action, address, contract_address, args)
- end
-
private
- def transcations(action, address, contract_address, args)
- params = {
- module: 'account', action: action,
- address: address, contractaddress: contract_address,
- startblock: args[:start_block], endblock: args[:end_block],
- page: args[:page], offset: args[:offset], sort: args[:sort]
- }.reject { |_, v| v.nil? }
- get(params)
+ # get a list of transactions
+ #
+ # @param [String] act accao a executar
+ # @param add (see normal_tx)
+ # @param cdd (see token_tx)
+ # @param ars (see normal_tx)
+ # @option ars (see normal_tx)
+ # @return (see normal_tx)
+ def transcations(act, add, cdd, **ars)
+ get(**{ module: 'account', action: act, address: add }.merge({
+ contractaddress: cdd,
+ startblock: ars[:start_block],
+ endblock: ars[:end_block],
+ page: ars[:page],
+ offset: ars[:offset],
+ sort: ars[:sort]
+ }.reject { |_, v| v.nil? }))
end
- end
-
- # class Tokens < Etht::Api
- class Tokens < Api
- def total_supply(contract_address)
- params = {
- module: 'stats', action: 'tokensupply',
- contractaddress: contract_address
- }
- get(params)
- end
-
- def balance(address, contract_address)
- params = {
- module: 'account', action: 'tokenbalance',
- address: address, contractaddress: contract_address
- }
- get(params)
- end
- end
-
- def self.configure
- yield config
- end
-
- def self.config
- @config ||= Config.new
- end
-
- def self.logger
- config.logger
- end
-
- configure do |config|
- config.key = ENV['ETHERSCAN_API_KEY']
end
end