The rockchain
package provides simple interfaces to coinmarketcap.com ticker and market cap data and blockchain.info ticker and Bitcoin wallet data. The current package does not yet support additional blockchain APIs, but will in the future. For now, it offers cryptocurrency market data retrieval and Bitcoin wallet transaction data retrieval via the two currently available APIs.
The default API for ticker and market cap data is the coinmarketcap.com
API. The site provides up-to-date cryptocurrency prices for Bitcoin and over a thousand “altcoins” (non-Bitcoin cryptocurrencies). While Bitcoin enjoys a large percentage of the total global cryptocurrency market cap, a number of altcoins also have large market caps, at least by current cryptocurrency standards. These include altcoins such as Ethereum (ETH) and Litecoin (LTC). Many others do not. And many of these that also do not have much to offer in terms of known technological or practical value are sometimes referred to as shitcoins; Buyer beware.
To look at the entire ticker from coinmarketcap.com
all you need is to call cap()
. Below are several ways you can use cap
. First return the entire ticker with cryptocurrency prices in USD.
library(rockchain)
cap()
#> # A tibble: 1,596 x 15
#> id name symbol rank price_usd price_btc `24h_volume_usd`
#> <chr> <chr> <chr> <fct> <dbl> <dbl> <dbl>
#> 1 bitcoin Bitcoin BTC 1 6756 1.00 4087320000
#> 2 ethereum Ethereum ETH 2 379 0.0565 1085240000
#> 3 ripple Ripple XRP 3 0.493 0.0000736 223847000
#> 4 bitcoin-c~ Bitcoin C~ BCH 4 660 0.0984 286396000
#> 5 litecoin Litecoin LTC 5 113 0.0169 253058000
#> 6 eos EOS EOS 6 5.76 0.000859 204308000
#> 7 cardano Cardano ADA 7 0.148 0.0000221 108073000
#> 8 stellar Stellar XLM 8 0.200 0.0000299 64459900
#> 9 neo NEO NEO 9 48.2 0.00719 58079400
#> 10 iota IOTA MIOTA 10 1.06 0.000158 25621200
#> # ... with 1,586 more rows, and 8 more variables: market_cap_usd <dbl>,
#> # available_supply <dbl>, total_supply <dbl>, max_supply <dbl>,
#> # percent_change_1h <dbl>, percent_change_24h <dbl>,
#> # percent_change_7d <dbl>, last_updated <dbl>
The first argument, crypto
, is NULL
by default. Alternatively, passing it an integer will return the top crypto
number of cryptocurrencies by market cap as a tibble data frame.
cap(crypto = 5)
#> # A tibble: 5 x 15
#> id name symbol rank price_usd price_btc `24h_volume_usd`
#> <chr> <chr> <chr> <fct> <dbl> <dbl> <dbl>
#> 1 bitcoin Bitcoin BTC 1 6756 1.00 4087320000
#> 2 ethereum Ethereum ETH 2 379 0.0565 1085240000
#> 3 ripple Ripple XRP 3 0.493 0.0000736 223847000
#> 4 bitcoin-ca~ Bitcoin C~ BCH 4 660 0.0984 286396000
#> 5 litecoin Litecoin LTC 5 113 0.0169 253058000
#> # ... with 8 more variables: market_cap_usd <dbl>, available_supply <dbl>,
#> # total_supply <dbl>, max_supply <dbl>, percent_change_1h <dbl>,
#> # percent_change_24h <dbl>, percent_change_7d <dbl>, last_updated <dbl>
If you want ticker data for specific cryptocurrencies, you can filter the results of cap()
or you can specify them during the call. Passing a single cryptocurrency ticker symbol vs. more than one technically uses two different API endpoints but the results are formatted to what you would expect. Note that symbols are not case sensitive: e.g., "btc"
is the same as "BTC"
.
cap(crypto = "BTC")
#> # A tibble: 1 x 15
#> id name symbol rank price_usd price_btc `24h_volume_usd`
#> <chr> <chr> <chr> <fct> <dbl> <dbl> <dbl>
#> 1 bitcoin Bitcoin BTC 1 6756 1.00 4087320000
#> # ... with 8 more variables: market_cap_usd <dbl>, available_supply <dbl>,
#> # total_supply <dbl>, max_supply <dbl>, percent_change_1h <dbl>,
#> # percent_change_24h <dbl>, percent_change_7d <dbl>, last_updated <dbl>
cap(crypto = c("ETH", "LTC"))
#> # A tibble: 2 x 15
#> id name symbol rank price_usd price_btc `24h_volume_usd`
#> <chr> <chr> <chr> <fct> <dbl> <dbl> <dbl>
#> 1 ethereum Ethereum ETH 2 379 0.0565 1085240000
#> 2 litecoin Litecoin LTC 5 113 0.0169 253058000
#> # ... with 8 more variables: market_cap_usd <dbl>, available_supply <dbl>,
#> # total_supply <dbl>, max_supply <dbl>, percent_change_1h <dbl>,
#> # percent_change_24h <dbl>, percent_change_7d <dbl>, last_updated <dbl>
The results always include USD and Bitcoin price, USD market cap and USD 24-hour trading volume by default. Using convert
to obtain price, market cap and volume in other currencies adds new columns onto the end of the table. convert
may be a vector. It may also include other cryptocurrency symbols, not just fiat currencies.
library(dplyr)
cap(crypto = "ETH", convert = c("EUR", "GBP")) %>% select(16:21)
#> # A tibble: 1 x 6
#> price_eur `24h_volume_eur` market_cap_eur price_gbp `24h_volume_gbp`
#> <chr> <chr> <chr> <chr> <chr>
#> 1 307.253838 880129640.0 30278163596.0 270.2772972 774210216.0
#> # ... with 1 more variable: market_cap_gbp <chr>
cap(crypto = "BTC", convert = "ETH") %>% select(16:18)
#> # A tibble: 1 x 3
#> price_eth `24h_volume_eth` market_cap_eth
#> <chr> <chr> <chr>
#> 1 17.6911817434 10703134.5788 299886972.0
The easiest way to obtain the total global market cap of all cryptocurrencies is to use the global endpoint of the coinmarketcap.com
API. This is done by passing crypto = "global"
.
cap(crypto = "global")
#> # A tibble: 1 x 7
#> last_updated total_market_cap total_24h_volume bitcoin_percentage_of_ma~
#> <int> <dbl> <dbl> <dbl>
#> 1 1522569267 253798766793 10051416887 45.1
#> # ... with 3 more variables: active_currencies <int>, active_assets <int>,
#> # active_markets <int>
At this point you have seen three different ways to specify crypto
: either as NULL
to yield the full ticker, an integer to yield to top coins by market cap, or as a character vector ticker symbols for the specific cryptocurrencies of interest.
If you are looking at Bitcoin only and working specifically with the blockchain.info
API, you can also obtain ticker information for Bitcoin with bcinfo
. There is only a fiat
argument, analogous to convert
, since blockchain.info
is specific to Bitcoin and ticker results from the API are only available in fiat currencies.
bcinfo()
#> # A tibble: 22 x 6
#> `15m` last buy sell symbol currency
#> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
#> 1 6703 6703 6703 6703 $ USD
#> 2 8725 8725 8725 8725 $ AUD
#> 3 22153 22153 22153 22153 R$ BRL
#> 4 8649 8649 8649 8649 $ CAD
#> 5 6396 6396 6396 6396 CHF CHF
#> 6 4047954 4047954 4047954 4047954 $ CLP
#> 7 42140 42140 42140 42140 ¥ CNY
#> 8 40543 40543 40543 40543 kr DKK
#> 9 5428 5428 5428 5428 € EUR
#> 10 4782 4782 4782 4782 £ GBP
#> # ... with 12 more rows
bcinfo(fiat = "GBP")
#> # A tibble: 1 x 6
#> `15m` last buy sell symbol currency
#> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
#> 1 4782 4782 4782 4782 £ GBP
Both of these functions wrap around ticker
and exist to provide some basic separation of the different behavior of the two APIs and the kind of data they provide. If you use ticker
directly, more attention should be paid to the different handling of ticker
arguments depending on whether you specify the default api = "coinmarketcap.com"
or the alternative api = "blockchain.info"
. Using the default API, the two functions are essentially the same, and slightly different with the alternative. See the help documentation for details. The following pairs are equivalent calls.
The current version of rockchain
supports Bitcoin wallet data retrieval from the Bitcoin blockchain using the blockchain.info
API. Future package versions will add support for other blockchains and currencies.
The wallet
function returns a list. This list also has class wallet
. The length of the wallet list is equal to the number of wallet addresses you pass to id
. The wallet will be a list even if you only pass a single address. This keeps the object structure consistent. It is also convenient to attach the wallet
class to the outer list rather than the inner tibbles; rockchain
functions operate on the former whereas a user is more likely to alter the latter after extracting from the wallet list.
Several convenient accessors are provided. These are simple getter functions. They are vectorized to return information pertaining to all elements of a wallet list.
id <- c("115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn", "1KennyH9grzif79WbaQDHpqgTnm25j4rRj")
w <- wallet(id) # a wallet list with two addresses
#> Recent API call. Waiting for turn. 9.98 seconds until next API call...
#> Recent API call. Waiting for turn. 9.94 seconds until next API call...
#> Recent API call. Waiting for turn. 9.98 seconds until next API call...
#> Recent API call. Waiting for turn. 9.86 seconds until next API call...
balance(w) # check the balance, vectorized
#> [1] 0.2694557 0.0000000
Here are all of the available getter functions.
hash(w)
#> [1] "00e8fd98ca34f195b020af4a8b1c7238663d4212"
#> [2] "cc97e1638381758e58d7e5885bb001d08d35f06d"
address(w)
#> [1] "115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn"
#> [2] "1KennyH9grzif79WbaQDHpqgTnm25j4rRj"
received(w) # total Bitcoin received
#> [1] 14.68013 0.00001
sent(w) # total Bitcoin sent
#> [1] 14.41068 0.00001
balance(w) # final Bitcoin balance
#> [1] 0.2694557 0.0000000
txn(w) # total number of transactions
#> [1] 118 2
transactions(w) # transaction details
#> # A tibble: 102 x 16
#> ver inputs weight block_height relayed_by out lock_time result
#> <int> <list> <int> <int> <chr> <list> <int> <int>
#> 1 1 <data.f~ 1000 509162 0.0.0.0 <data~ 0 0
#> 2 1 <data.f~ 32599 498751 0.0.0.0 <data~ 0 6.00e6
#> 3 1 <data.f~ 49944 498750 0.0.0.0 <data~ 0 1.08e7
#> 4 1 <data.f~ 1164 479819 85.224.105~ <data~ 479808 1.17e6
#> 5 1 <data.f~ 42088 478796 193.49.43.~ <data~ 0 9.00e6
#> 6 1 <data.f~ 24516 478796 176.9.110.4 <data~ 0 -7.07e8
#> 7 1 <data.f~ 900 471511 73.153.220~ <data~ 471510 -7.34e8
#> 8 1 <data.f~ 1344 471189 136.243.13~ <data~ 0 4.00e6
#> 9 1 <data.f~ 904 470322 217.111.66~ <data~ 0 5.00e5
#> 10 1 <data.f~ 1360 470040 176.126.85~ <data~ 0 7.69e6
#> # ... with 92 more rows, and 8 more variables: size <int>, time <int>,
#> # tx_index <int>, vin_sz <int>, hash <chr>, vout_sz <int>, rbf <lgl>,
#> # address <chr>
Note the discrepancy between the number of transactions reported by txn
and the number of rows in the transaction details tibble returned by transactions
for the second wallet address: 101 vs. 115. There are two important things to note going on here.
First, txn
always provides the total number of wallet transactions. However, wallet
does not automatically retrieve the complete transaction details history from the blockchain.info
API. In fact, it only gives you 50 transactions by default. wallet
makes repeated calls to the API for you, breaking calls up using a series of transaction offsets, so that you are not only given the first 50 if there are more available. wallet
still imposes a safety cap at 100 total transactions in the event you are carelessly requesting all transactions from a wallet that has an extensive transaction history. You can override this by setting a higher cap beyond the default tx_max = 100
or set it to NULL
for “unlimited”, though for large transaction records there is not real intent to support to NULL
option. You will always be constrained by the limits imposed by the API.
But that brings the total to 100 whereas the total transactions in the table is 101. The final transaction comes from a row bind of the two wallets. These can be filtered using the final column, address
, that has been added to the table.
If you have trouble connecting, wallet
will retry for you, up to max_attempts
times. The default is ten attempts. It is not unusual to be rejected by the API if you make many calls. Notifications are printed to the console if wallet
has to try more than once as well as if it fails max_attempts
times. By default, wallet
will not call the blockchain.info
API more than once every ten seconds. You can adjust this with, e.g., options(rockchain_antiddos = 1)
, but if you make many calls it may make sense to request your own API key from blockchain.info
.
By default, the blockchain.info
API returns Bitcoin values in Satoshis. One Satoshi is the smallest unit of value, equal to \(`1 / 10^7`\) Bitcoin. But since many APIs and websites report value in Bitcoin, rockchain
does the same. This can be switched with satoshi = TRUE
. This affects the total received, total sent, final balance, and the value
column inside the out
data frames that appear in the transaction details table.
id <- "115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn"
w <- wallet(id)
#> Recent API call. Waiting for turn. 9.74 seconds until next API call...
#> Recent API call. Waiting for turn. 9.89 seconds until next API call...
#> Recent API call. Waiting for turn. 9.93 seconds until next API call...
w2 <- wallet(id, satoshi = TRUE)
#> Recent API call. Waiting for turn. 9.86 seconds until next API call...
#> Recent API call. Waiting for turn. 9.95 seconds until next API call...
#> Recent API call. Waiting for turn. 9.96 seconds until next API call...
balance(w2) == balance(w) * 100000000
#> [1] TRUE
An offset
can used passed to shift the starting point of the transaction record. The default offset is zero.
w2 <- wallet(id, offset = 10)
#> Recent API call. Waiting for turn. 9.88 seconds until next API call...
#> Recent API call. Waiting for turn. 9.93 seconds until next API call...
#> Recent API call. Waiting for turn. 9.95 seconds until next API call...
transactions(w2)$tx_index[1] == transactions(w)$tx_index[11]
#> [1] TRUE
The package provides one complete and three shorthand convenience functions for converting among different units of measure for Bitcoin. As the value of Bitcoin has grown by orders of magnitude, there is an increasing push for valuation to be expressed in larger, more intuitive numbers using smaller units. Other units include mBTC, bits, and satoshi. Satoshi is the smallest, non-divisible unit of a Bitcoin. There are 100 million satoshi in a Bitcoin. Many people are advocating for the use of bits. One bit is equal to 100 satoshi. Therefore bits can have at most the familiar two decimal places. mBTC are one one-thousandth of a Bitcoin. Bits can also be thought of as one one-millionth of a Bitcoin, or as micro BTC.
convert_btc(1, from = "BTC", to = "mBTC")
#> [1] 1000
convert_btc(1, "BTC", "bits")
#> [1] 1000000
convert_btc(1, "BTC", "satoshi")
#> [1] 100000000
convert_btc(0.001, "mBTC", "bits")
#> [1] 1
convert_btc(1, "mBTC", "bitcoin")
#> [1] 0.001
convert_btc(100, "satoshi", "bits")
#> [1] 1
# Shorthand functions assume value is in Bitcoin
satoshi(0.00000001)
#> [1] 1
bits(0.000001)
#> [1] 1
mbtc(0.001)
#> [1] 1