R/in_out.R

Defines functions in_out

Documented in in_out

#' Summarize ETH flow for an address
#'
#' Summarize inflow and outflow of ETH from an address.
#'
#' @param address Character. A single externally owned account (user Ethereum
#'   address).
#' @param api_key An Etherscan API key (see Details).
#' @param startblock Starting block for transaction query. Default is 0.
#' @param endblock Ending block for transaction query. Default is 999999999.
#' @param startdate Optional `Date` or `POSIXct` object defining the start date
#'   or datetime for the resulting list of transactions to be filtered to. If
#'   `startdate` is provided, `startblock` is ignored.If a `Date` object is
#'   provided, timezone is assumed to be UTC, and all transactions up to
#'   midnight of that date will be included in the filtered result. For
#'   `POSIXct` objects, timezone is taken from the object. Note that,
#'   `startdate` is applied as a filter _after_ downloading transactions, and so
#'   settings a value that is later than the earliest transaction sent/received
#'   by the address does not speed up the download process.
#' @param enddate Optional `Date` or `POSIXct` object defining the end date
#'   or datetime for the resulting list of transactions to be filtered to.
#'   Starting block for transaction query. If `enddate` is provided, `endblock`
#'   is ignored. If a `Date` object is provided, timezone is assumed to be UTC,
#'   and all transactions up to midnight of that date will be included in the
#'   filtered result. For `POSIXct` objects, timezone is taken from the object.
#' @param get_names Logical. Get contract names for verified contracts?
#' @return A summary of inflow and outflow of ETH from an address.
#' @keywords Ethereum, contract, blockchain, cryptocurrency, crypto, ETH
#' @importFrom dplyr across arrange bind_rows desc filter group_by mutate select summarise
#' @importFrom tidyr pivot_wider
#' @importFrom magrittr %>%
#' @export
in_out <- function(address, api_key, startblock=0, endblock=999999999,
                   startdate, enddate,
                   get_names=FALSE) {
  address <- tolower(address)
  txs <- get_txs(address, api_key, startblock=startblock, endblock=endblock,
                 startdate=startdate, enddate=enddate)
  txs_i <- get_txs(address, api_key, type='internal',
                   startblock=startblock, endblock=endblock,
                   startdate=startdate, enddate=enddate)
  froms <- dplyr::bind_rows(
    list(normal=dplyr::select(txs, address=from, value_eth),
         internal=dplyr::select(txs_i, address=from, value_eth)),
    .id='type'
  ) %>% dplyr::filter(address != !!address)
  tos <- dplyr::select(txs, address=to, value_eth) %>%
    dplyr::filter(address != !!address)
  if(nrow(froms)==0 && (nrow(tos)==0)) {
    warning('No ETH sent or received during selected timeframe. Returning NULL.')
    return(NULL)
  }
  if(nrow(froms)==0)
    message('No ETH received during selected timeframe.')
  if(nrow(tos)==0)
    message('No ETH sent during selected timeframe.')
  flow <- dplyr::bind_rows(list(eth_in=froms, eth_out=tos), .id='direction') %>%
    dplyr::group_by(direction, address) %>%
    dplyr::summarise(value=sum(value_eth), .groups='drop') %>%
    tidyr::pivot_wider(names_from=direction, values_from=value)
  if(!'eth_in' %in% names(flow)) flow$eth_in <- 0
  if(!'eth_out' %in% names(flow)) flow$eth_out <- 0
  flow <- flow %>%
    dplyr::mutate(dplyr::across(eth_in:eth_out, ~ifelse(is.na(.x), 0, .x)),
                  net=eth_in - eth_out,
                  roi_pct=eth_in/eth_out*100,
                  roi_pct=ifelse(is.nan(roi_pct), NA, roi_pct)) %>%
    dplyr::arrange(dplyr::desc(net))

  if(isTRUE(get_names)) {
    message('Getting contract names...')
    flow$name <- get_name(flow$address, api_key)
  }

  flow
}
dapped/eth documentation built on Oct. 23, 2021, 4:42 a.m.