mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Ethplorer (#814)
* Add separate view for finbrain for crypto curreny sentiment analysis * Move json with symbols to separate directory, little refactoring, update readme * Add screenshot of finbrain for PolkaDot * Add ethplorer model and view * Onchain controller * Add webbrowser for etherscan and ethplorer * Add very long number formatter * Add hugo docs * Change names, remove prints from model, help as one string * Add key for ethplorer, convert values based of token decimals number, apply changes from PR * fix docs * fix docs * Add address command that load ethereum address * Adjust hugo-docs
This commit is contained in:
2
README.md
vendored
2
README.md
vendored
@@ -268,6 +268,7 @@ These are the ones where a key is necessary:
|
||||
* Twitter: https://developer.twitter.com
|
||||
* Coinbase Pro API: https://docs.pro.coinbase.com/
|
||||
* Whale Alert API: https://docs.whale-alert.io/
|
||||
* Ethplorer API: https://github.com/EverexIO/Ethplorer/wiki/Ethplorer-API
|
||||
|
||||
When these are obtained, don't forget to update [config_terminal.py](/gamestonk_terminal/config_terminal.py).
|
||||
|
||||
@@ -292,6 +293,7 @@ Alternatively, you can also set them to the following environment variables:
|
||||
| [Twitter](https://developer.twitter.com) | GT_API_TWITTER_KEY <br/> GT_API_TWITTER_SECRET_KEY <br/> GT_API_TWITTER_BEARER_TOKEN |
|
||||
| [Coinbase](https://docs.pro.coinbase.com/) | GT_API_COINBASE_KEY <br/> GT_API_COINBASE_SECRET <br/> GT_API_COINBASE_PASS_PHRASE |
|
||||
| [Whale Alert](https://docs.whale-alert.io/) | GT_API_WHALE_ALERT_KEY |
|
||||
| [Ethplorer](https://github.com/EverexIO/Ethplorer/wiki/Ethplorer-API) | GT_API_ETHPLORER_KEY |
|
||||
|
||||
Example:
|
||||
```
|
||||
|
||||
@@ -96,3 +96,6 @@ API_COINBASE_PASS_PHRASE = os.getenv("GT_API_COINBASE_PASS_PHRASE") or "REPLACE_
|
||||
|
||||
# https://docs.whale-alert.io/
|
||||
API_WHALE_ALERT_KEY = os.getenv("GT_API_WHALE_ALERT_KEY") or "REPLACE_ME"
|
||||
|
||||
# https://github.com/EverexIO/Ethplorer/wiki/Ethplorer-API
|
||||
API_ETHPLORER_KEY = os.getenv("GT_API_ETHPLORER_KEY") or "freekey"
|
||||
|
||||
@@ -76,7 +76,6 @@ def long_number_format_with_type_check(x: Union[int, float]) -> Union[str, Any]:
|
||||
Returns
|
||||
-------
|
||||
Union[str, Any]
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(x, (int, float)) and x < 10 ** 18:
|
||||
@@ -86,3 +85,36 @@ def long_number_format_with_type_check(x: Union[int, float]) -> Union[str, Any]:
|
||||
|
||||
def replace_underscores_in_column_names(string: str) -> str:
|
||||
return string.title().replace("_", " ")
|
||||
|
||||
|
||||
def very_long_number_formatter(num: Union[str, int, float]) -> str:
|
||||
"""Apply nice string format for very big numbers like Trillions, Quadrillions, Billions etc.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
num: Union[str, int, float]
|
||||
number to format
|
||||
Returns
|
||||
-------
|
||||
str:
|
||||
formatted number
|
||||
"""
|
||||
|
||||
if isinstance(num, str):
|
||||
try:
|
||||
num = float(num)
|
||||
except (TypeError, ValueError):
|
||||
return str(num)
|
||||
|
||||
if isinstance(num, (int, float)):
|
||||
num = int(num)
|
||||
magnitude = 0
|
||||
while abs(num) >= 1000 and magnitude <= 3:
|
||||
magnitude += 1
|
||||
num /= 1000.0
|
||||
num = round(num, 1)
|
||||
return "{}{}".format(
|
||||
f"{num:f}".rstrip("0").rstrip("."),
|
||||
["", "K", "M", "B", "T"][magnitude],
|
||||
)
|
||||
return num
|
||||
|
||||
457
gamestonk_terminal/cryptocurrency/onchain/ethplorer_model.py
Normal file
457
gamestonk_terminal/cryptocurrency/onchain/ethplorer_model.py
Normal file
@@ -0,0 +1,457 @@
|
||||
"""Ethplorer model"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import textwrap
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional
|
||||
from time import sleep
|
||||
import pandas as pd
|
||||
import requests
|
||||
from gamestonk_terminal.cryptocurrency.dataframe_helpers import create_df_index
|
||||
import gamestonk_terminal.config_terminal as cfg
|
||||
|
||||
|
||||
def split_cols_with_dot(column: str) -> str:
|
||||
"""Split column name in data frame columns whenever there is a dot between 2 words.
|
||||
E.g. price.availableSupply -> priceAvailableSupply.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
column: str
|
||||
Pandas dataframe column value
|
||||
|
||||
Returns
|
||||
-------
|
||||
str:
|
||||
Value of column with replaced format.
|
||||
"""
|
||||
|
||||
def replace(string: str, char: str, index: int) -> str:
|
||||
"""Helper method which replaces values with dot as a separator and converts it to camelCase format
|
||||
|
||||
Parameters
|
||||
----------
|
||||
string: str
|
||||
String in which we remove dots and convert it to camelcase format.
|
||||
char: str
|
||||
First letter of given word.
|
||||
index:
|
||||
Index of string element.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str:
|
||||
Camel case string with removed dots. E.g. price.availableSupply -> priceAvailableSupply.
|
||||
"""
|
||||
|
||||
return string[:index] + char + string[index + 1 :]
|
||||
|
||||
if "." in column:
|
||||
part1, part2 = column.split(".")
|
||||
part2 = replace(part2, part2[0].upper(), 0)
|
||||
return part1 + part2
|
||||
return column
|
||||
|
||||
|
||||
def enrich_social_media(dct: dict) -> None:
|
||||
"""Searching inside dictionary if there are any information about twitter, reddit or coingecko. If yes it
|
||||
updates dictionary with url to given social media site.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dct: dict
|
||||
Dictionary in which we search for coingecko, twitter or reddit url.
|
||||
"""
|
||||
|
||||
social_media = {
|
||||
"twitter": "https://www.twitter.com/",
|
||||
"reddit": "https://www.reddit.com/r/",
|
||||
"coingecko": "https://www.coingecko.com/en/coins/",
|
||||
}
|
||||
|
||||
for k, v in social_media.items():
|
||||
if k in dct:
|
||||
dct[k] = v + dct[k]
|
||||
|
||||
|
||||
def make_request(endpoint: str, address: Optional[str] = None, **kwargs: Any) -> dict:
|
||||
"""Helper method that handles request for Ethplorer API [Source: https://ethplorer.io/]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
endpoint: str
|
||||
endpoint which we want to query e.g. https://api.ethplorer.io/<endpoint><arg>?=apiKey=freekey
|
||||
address: str
|
||||
balance argument for given endpoint. In most cases it's tx hash, or eth balance.
|
||||
kwargs: Any
|
||||
Additional keywords arguments e.g. limit of transactions
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
dictionary with response data
|
||||
"""
|
||||
|
||||
base_url = "https://api.ethplorer.io/"
|
||||
url = f"{base_url}{endpoint}"
|
||||
|
||||
if address:
|
||||
url = url + "/" + address
|
||||
|
||||
url += f"?apiKey={cfg.API_ETHPLORER_KEY}"
|
||||
|
||||
if "limit" in kwargs:
|
||||
url += f"&limit={kwargs['limit']}"
|
||||
|
||||
sleep(0.5) # Limit is 2 API calls per 1 sec.
|
||||
response = requests.get(url).json()
|
||||
if "error" in response:
|
||||
raise Exception(
|
||||
f"Error: {response['error']['code']}. Message: {response['error']['message']}\n",
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def get_token_decimals(address: str) -> Optional[int]:
|
||||
"""Helper methods that gets token decimals number. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Blockchain balance e.g. 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with list of tokens and their balances.
|
||||
"""
|
||||
response = make_request("getTokenInfo", address)
|
||||
if response and "decimals" in response:
|
||||
return 10 ** int(response["decimals"])
|
||||
return None
|
||||
|
||||
|
||||
def get_address_info(address: str) -> pd.DataFrame:
|
||||
"""Get info about tokens on you ethereum blockchain balance. Eth balance, balance of all tokens which
|
||||
have name and symbol. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Blockchain balance e.g. 0x3cD751E6b0078Be393132286c442345e5DC49699
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with list of tokens and their balances.
|
||||
"""
|
||||
|
||||
response = make_request("getAddressInfo", address)
|
||||
|
||||
if "tokens" in response:
|
||||
tokens = response.pop("tokens")
|
||||
|
||||
for token in tokens:
|
||||
token_info = token.pop("tokenInfo")
|
||||
token.update(
|
||||
{
|
||||
"tokenName": token_info.get("name"),
|
||||
"tokenSymbol": token_info.get("symbol"),
|
||||
"tokenAddress": token_info.get("balance"),
|
||||
"balance": token.get("balance")
|
||||
/ (10 ** int(token_info.get("decimals"))),
|
||||
}
|
||||
)
|
||||
else:
|
||||
token_info = response.get("tokenInfo") or {}
|
||||
tokens = [
|
||||
{
|
||||
"tokenName": token_info.get("name"),
|
||||
"tokenSymbol": token_info.get("symbol"),
|
||||
"tokenAddress": token_info.get("balance"),
|
||||
"balance": token_info.get("balance")
|
||||
/ (10 ** int(token_info.get("decimals"))),
|
||||
}
|
||||
]
|
||||
|
||||
eth = response["ETH"] or {}
|
||||
eth_balance = eth.get("balance")
|
||||
eth_row = [
|
||||
"Ethereum",
|
||||
"ETH",
|
||||
"0x0000000000000000000000000000000000000000",
|
||||
eth_balance,
|
||||
]
|
||||
|
||||
cols = [
|
||||
"tokenName",
|
||||
"tokenSymbol",
|
||||
"tokenAddress",
|
||||
"balance",
|
||||
]
|
||||
df = pd.DataFrame(tokens)[cols]
|
||||
eth_row_df = pd.DataFrame([eth_row], columns=cols)
|
||||
df = pd.concat([eth_row_df, df], ignore_index=True)
|
||||
df = df[df["tokenName"].notna()]
|
||||
create_df_index(df, "index")
|
||||
return df
|
||||
|
||||
|
||||
def get_top_tokens() -> pd.DataFrame:
|
||||
"""Get top 50 tokens. [Source: Ethplorer]
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with list of top 50 tokens.
|
||||
"""
|
||||
|
||||
response = make_request("getTopTokens")
|
||||
tokens = response["tokens"]
|
||||
df = pd.DataFrame(tokens)[
|
||||
[
|
||||
"name",
|
||||
"symbol",
|
||||
"price",
|
||||
"txsCount",
|
||||
"transfersCount",
|
||||
"holdersCount",
|
||||
"twitter",
|
||||
"coingecko",
|
||||
]
|
||||
]
|
||||
df["price"] = df["price"].apply(lambda x: x["rate"] if x and "rate" in x else None)
|
||||
create_df_index(df, "rank")
|
||||
return df
|
||||
|
||||
|
||||
def get_top_token_holders(address) -> pd.DataFrame:
|
||||
"""Get info about top token holders. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token balance e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with list of top token holders.
|
||||
"""
|
||||
|
||||
response = make_request("getTopTokenHolders", address, limit=100)
|
||||
df = pd.DataFrame(response["holders"])
|
||||
sleep(0.5)
|
||||
token_decimals_divider = get_token_decimals(address)
|
||||
if token_decimals_divider:
|
||||
df["balance"] = df["balance"] / token_decimals_divider
|
||||
return df
|
||||
|
||||
|
||||
def get_address_history(address) -> pd.DataFrame:
|
||||
"""Get information about balance historical transactions. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Blockchain balance e.g. 0x3cD751E6b0078Be393132286c442345e5DC49699
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with balance historical transactions (last 100)
|
||||
"""
|
||||
response = make_request("getAddressHistory", address, limit=100)
|
||||
operations = response.pop("operations")
|
||||
if operations:
|
||||
for operation in operations:
|
||||
token = operation.pop("tokenInfo")
|
||||
if token:
|
||||
operation["token"] = token["name"]
|
||||
operation["tokenAddress"] = token["address"]
|
||||
operation["decimals"] = int(token["decimals"])
|
||||
operation["timestamp"] = datetime.fromtimestamp(operation["timestamp"])
|
||||
|
||||
df = pd.DataFrame(operations)
|
||||
cols = ["timestamp", "transactionHash", "token", "value"]
|
||||
df["value"] = df["value"].astype(float) / (10 ** df["decimals"])
|
||||
if df.empty:
|
||||
return pd.DataFrame(columns=cols)
|
||||
|
||||
return df[cols]
|
||||
|
||||
|
||||
def get_token_info(address) -> pd.DataFrame:
|
||||
"""Get info about ERC20 token. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token balance e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with information about provided ERC20 token.
|
||||
"""
|
||||
|
||||
response = make_request("getTokenInfo", address)
|
||||
decimals = response.pop("decimals") if "decimals" in response else None
|
||||
for name in [
|
||||
"issuancesCount",
|
||||
"lastUpdated",
|
||||
"image",
|
||||
"transfersCount",
|
||||
"ethTransfersCount",
|
||||
]:
|
||||
try:
|
||||
response.pop(name)
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
enrich_social_media(response)
|
||||
df = pd.json_normalize(response)
|
||||
df.columns = [split_cols_with_dot(x) for x in df.columns.tolist()]
|
||||
if "priceTs" in df:
|
||||
df.drop("priceTs", axis=1, inplace=True)
|
||||
|
||||
for col in [
|
||||
"owner",
|
||||
"slot",
|
||||
"facebook",
|
||||
"priceDiff",
|
||||
"priceDiff7d",
|
||||
"priceDiff30d",
|
||||
"priceVolDiff1",
|
||||
"priceVolDiff7",
|
||||
"priceVolDiff30",
|
||||
"priceCurrency",
|
||||
]:
|
||||
if col in df.columns:
|
||||
df.drop(col, axis=1, inplace=True)
|
||||
|
||||
df["totalSupply"] = df["totalSupply"].astype(float) / (10 ** int(decimals))
|
||||
|
||||
df = df.T.reset_index()
|
||||
df.columns = ["Metric", "Value"]
|
||||
df["Value"] = df["Value"].apply(
|
||||
lambda x: "\n".join(textwrap.wrap(x, width=70)) if isinstance(x, str) else x
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
def get_tx_info(tx_hash) -> pd.DataFrame:
|
||||
"""Get info about transaction. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tx_hash: str
|
||||
Transaction hash e.g. 0x9dc7b43ad4288c624fdd236b2ecb9f2b81c93e706b2ffd1d19b112c1df7849e6
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with information about ERC20 token transaction.
|
||||
"""
|
||||
decimals = None
|
||||
response = make_request("getTxInfo", tx_hash)
|
||||
try:
|
||||
response.pop("logs")
|
||||
operations = response.pop("operations")[0]
|
||||
if operations:
|
||||
operations.pop("addresses")
|
||||
token = operations.pop("tokenInfo")
|
||||
decimals = token.get("decimals")
|
||||
if token:
|
||||
operations["token"] = token["name"]
|
||||
operations["tokenAddress"] = token["address"]
|
||||
operations["timestamp"] = datetime.fromtimestamp(operations["timestamp"])
|
||||
response.update(operations)
|
||||
response.pop("input")
|
||||
|
||||
df = pd.Series(response)
|
||||
|
||||
if decimals:
|
||||
for col in ["intValue", "value"]:
|
||||
df[col] = float(df[col]) // (10 ** int(decimals))
|
||||
|
||||
df = df.to_frame().reset_index()
|
||||
df.columns = ["Metric", "Value"]
|
||||
except KeyError:
|
||||
return pd.DataFrame()
|
||||
return df
|
||||
|
||||
|
||||
def get_token_history(address) -> pd.DataFrame:
|
||||
"""Get info about token historical transactions. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token e.g. 0xf3db5fa2c66b7af3eb0c0b782510816cbe4813b8
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with token historical transactions.
|
||||
"""
|
||||
|
||||
response = make_request("getTokenHistory", address, limit=1000)
|
||||
all_operations = []
|
||||
operations = response["operations"]
|
||||
try:
|
||||
first_row = operations[0]["tokenInfo"]
|
||||
name, symbol, _ = (
|
||||
first_row.get("name"),
|
||||
first_row.get("symbol"),
|
||||
first_row.get("balance"),
|
||||
)
|
||||
decimals = first_row.get("decimals")
|
||||
except Exception:
|
||||
name, symbol = "", ""
|
||||
decimals = None
|
||||
|
||||
for operation in operations:
|
||||
operation.pop("type")
|
||||
operation.pop("tokenInfo")
|
||||
operation["timestamp"] = datetime.fromtimestamp(operation["timestamp"])
|
||||
all_operations.append(operation)
|
||||
|
||||
df = pd.DataFrame(all_operations)
|
||||
if df.empty:
|
||||
return df
|
||||
df[["name", "symbol"]] = name, symbol
|
||||
df["value"] = df["value"].astype(float) / (10 ** int(decimals))
|
||||
return df[["timestamp", "name", "symbol", "value", "from", "to", "transactionHash"]]
|
||||
|
||||
|
||||
def get_token_historical_price(address) -> pd.DataFrame:
|
||||
"""Get token historical prices with volume and market cap, and average price. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token e.g. 0xf3db5fa2c66b7af3eb0c0b782510816cbe4813b8
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame:
|
||||
DataFrame with token historical prices.
|
||||
"""
|
||||
|
||||
response = make_request("getTokenPriceHistoryGrouped", address)
|
||||
data = response["history"]
|
||||
data.pop("current")
|
||||
prices = data.get("prices")
|
||||
if not prices:
|
||||
return pd.DataFrame()
|
||||
|
||||
prices_df = pd.DataFrame(prices)
|
||||
prices_df["ts"] = prices_df["ts"].apply(lambda x: datetime.fromtimestamp(x))
|
||||
prices_df.drop("tmp", axis=1, inplace=True)
|
||||
return prices_df[
|
||||
["date", "open", "close", "high", "low", "volumeConverted", "cap", "average"]
|
||||
]
|
||||
423
gamestonk_terminal/cryptocurrency/onchain/ethplorer_view.py
Normal file
423
gamestonk_terminal/cryptocurrency/onchain/ethplorer_view.py
Normal file
@@ -0,0 +1,423 @@
|
||||
"""Ethplorer view"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import os
|
||||
from tabulate import tabulate
|
||||
from gamestonk_terminal.helper_funcs import export_data
|
||||
from gamestonk_terminal.cryptocurrency.dataframe_helpers import (
|
||||
very_long_number_formatter,
|
||||
)
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.cryptocurrency.onchain import ethplorer_model
|
||||
|
||||
|
||||
def display_address_info(
|
||||
address: str,
|
||||
top: int = 15,
|
||||
sortby: str = "index",
|
||||
descend: bool = True,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display info about tokens for given ethereum blockchain balance e.g. ETH balance, balance of all tokens with
|
||||
name and symbol. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Ethereum balance.
|
||||
top: int
|
||||
Limit of transactions. Maximum 100
|
||||
sortby: str
|
||||
Key to sort by.
|
||||
descend: str
|
||||
Sort in descending order.
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_address_info(address)
|
||||
df_data = df.copy()
|
||||
df = df.sort_values(by=sortby, ascending=descend)
|
||||
df["balance"] = df["balance"].apply(
|
||||
lambda x: very_long_number_formatter(x) if x >= 10000 else round(float(x), 4)
|
||||
)
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(top),
|
||||
headers=df.columns,
|
||||
floatfmt=".2f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"balance",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_top_tokens(
|
||||
top: int = 15,
|
||||
sortby: str = "rank",
|
||||
descend: bool = True,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display top ERC20 tokens [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
top: int
|
||||
Limit of transactions. Maximum 100
|
||||
sortby: str
|
||||
Key to sort by.
|
||||
descend: str
|
||||
Sort in descending order.
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_top_tokens()
|
||||
df_data = df.copy()
|
||||
df.fillna("", inplace=True)
|
||||
df = df.sort_values(by=sortby, ascending=descend)
|
||||
for col in ["txsCount", "transfersCount", "holdersCount"]:
|
||||
if col in df.columns:
|
||||
df[col] = df[col].apply(lambda x: very_long_number_formatter(x))
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(top),
|
||||
headers=df.columns,
|
||||
floatfmt=".2f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"top",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_top_token_holders(
|
||||
address: str,
|
||||
top: int = 10,
|
||||
sortby: str = "balance",
|
||||
descend: bool = False,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display info about top ERC20 token holders. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token balance e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
top: int
|
||||
Limit of transactions. Maximum 100
|
||||
sortby: str
|
||||
Key to sort by.
|
||||
descend: str
|
||||
Sort in descending order.
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_top_token_holders(address)
|
||||
df_data = df.copy()
|
||||
df = df.sort_values(by=sortby, ascending=descend)
|
||||
df["balance"] = df["balance"].apply(lambda x: very_long_number_formatter(x))
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(top),
|
||||
headers=df.columns,
|
||||
floatfmt=".2f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"holders",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_address_history(
|
||||
address: str,
|
||||
top: int = 10,
|
||||
sortby: str = "timestamp",
|
||||
descend: bool = False,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display information about balance historical transactions. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Ethereum nlockchain balance e.g. 0x3cD751E6b0078Be393132286c442345e5DC49699
|
||||
top: int
|
||||
Limit of transactions. Maximum 100
|
||||
sortby: str
|
||||
Key to sort by.
|
||||
descend: str
|
||||
Sort in descending order.
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_address_history(address)
|
||||
df_data = df.copy()
|
||||
df = df.sort_values(by=sortby, ascending=descend)
|
||||
df["value"] = df["value"].apply(
|
||||
lambda x: very_long_number_formatter(x) if x >= 10000 else round(float(x), 4)
|
||||
)
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(top),
|
||||
headers=df.columns,
|
||||
floatfmt=".0f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"hist",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_token_info(
|
||||
address: str,
|
||||
social: bool = False,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display info about ERC20 token. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token balance e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
social: bool
|
||||
Flag to display social media links
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_token_info(address)
|
||||
df_data = df.copy()
|
||||
df["Value"] = df["Value"].apply(lambda x: very_long_number_formatter(x))
|
||||
|
||||
socials = ["website", "telegram", "reddit", "twitter", "coingecko"]
|
||||
if social:
|
||||
df = df[df["Metric"].isin(["balance", "name", "symbol"] + socials)]
|
||||
else:
|
||||
df = df[~df["Metric"].isin(socials)]
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df,
|
||||
headers=df.columns,
|
||||
floatfmt=".0f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"info",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_tx_info(
|
||||
tx_hash: str,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display info about transaction. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tx_hash: str
|
||||
Transaction hash e.g. 0x9dc7b43ad4288c624fdd236b2ecb9f2b81c93e706b2ffd1d19b112c1df7849e6
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_tx_info(tx_hash)
|
||||
df_data = df.copy()
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df,
|
||||
headers=df.columns,
|
||||
floatfmt=".0f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"tx",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_token_history(
|
||||
address: str,
|
||||
top: int = 10,
|
||||
sortby: str = "timestamp",
|
||||
hash_: bool = False,
|
||||
descend: bool = False,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display info about token history. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token balance e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
top: int
|
||||
Limit of transactions. Maximum 100
|
||||
sortby: str
|
||||
Key to sort by.
|
||||
descend: str
|
||||
Sort in descending order.
|
||||
hash_: bool,
|
||||
Flag to show transaction hash.
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_token_history(address)
|
||||
df_data = df.copy()
|
||||
if df.empty:
|
||||
print(f"No results found for balance: {address}\n")
|
||||
return
|
||||
|
||||
df["value"] = df["value"].apply(lambda x: very_long_number_formatter(x))
|
||||
df = df.sort_values(by=sortby, ascending=descend)
|
||||
|
||||
if hash_:
|
||||
df.drop(["from", "to"], axis=1, inplace=True)
|
||||
else:
|
||||
df.drop("transactionHash", inplace=True, axis=1)
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(top),
|
||||
headers=df.columns,
|
||||
floatfmt=".2f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"th",
|
||||
df_data,
|
||||
)
|
||||
|
||||
|
||||
def display_token_historical_prices(
|
||||
address: str,
|
||||
top: int = 30,
|
||||
sortby: str = "date",
|
||||
descend: bool = False,
|
||||
export: str = "",
|
||||
) -> None:
|
||||
"""Display token historical prices with volume and market cap, and average price. [Source: Ethplorer]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
address: str
|
||||
Token balance e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
top: int
|
||||
Limit of transactions. Maximum 100
|
||||
sortby: str
|
||||
Key to sort by.
|
||||
descend: str
|
||||
Sort in descending order.
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
|
||||
df = ethplorer_model.get_token_historical_price(address)
|
||||
df_data = df.copy()
|
||||
|
||||
if df.empty:
|
||||
print(f"No results found for balance: {address}\n")
|
||||
return
|
||||
|
||||
df["volumeConverted"] = df["volumeConverted"].apply(
|
||||
lambda x: very_long_number_formatter(x)
|
||||
)
|
||||
df["cap"] = df["cap"].apply(lambda x: very_long_number_formatter(x))
|
||||
df = df.sort_values(by=sortby, ascending=descend)
|
||||
|
||||
if gtff.USE_TABULATE_DF:
|
||||
print(
|
||||
tabulate(
|
||||
df.head(top),
|
||||
headers=df.columns,
|
||||
floatfmt=".2f",
|
||||
showindex=False,
|
||||
tablefmt="fancy_grid",
|
||||
),
|
||||
"\n",
|
||||
)
|
||||
else:
|
||||
print(df.to_string, "\n")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"prices",
|
||||
df_data,
|
||||
)
|
||||
@@ -4,6 +4,7 @@ __docformat__ = "numpy"
|
||||
import os
|
||||
import argparse
|
||||
from typing import List
|
||||
|
||||
from prompt_toolkit.completion import NestedCompleter
|
||||
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
@@ -18,6 +19,7 @@ from gamestonk_terminal.helper_funcs import (
|
||||
from gamestonk_terminal.cryptocurrency.onchain import (
|
||||
ethgasstation_view,
|
||||
whale_alert_view,
|
||||
ethplorer_view,
|
||||
)
|
||||
|
||||
# pylint: disable=R1732
|
||||
@@ -34,7 +36,33 @@ class OnchainController:
|
||||
"quit",
|
||||
]
|
||||
|
||||
CHOICES_COMMANDS = ["gwei", "whales"]
|
||||
SPECIFIC_CHOICES = {
|
||||
"account": [
|
||||
"balance",
|
||||
"hist",
|
||||
],
|
||||
"token": [
|
||||
"info",
|
||||
"th",
|
||||
"prices",
|
||||
"holders",
|
||||
],
|
||||
"tx": ["tx"],
|
||||
}
|
||||
|
||||
CHOICES_COMMANDS = [
|
||||
"gwei",
|
||||
"whales",
|
||||
"balance",
|
||||
"top",
|
||||
"holders",
|
||||
"tx",
|
||||
"hist",
|
||||
"info",
|
||||
"th",
|
||||
"prices",
|
||||
"address",
|
||||
]
|
||||
|
||||
CHOICES += CHOICES_COMMANDS
|
||||
|
||||
@@ -45,6 +73,8 @@ class OnchainController:
|
||||
"cmd",
|
||||
choices=self.CHOICES,
|
||||
)
|
||||
self.address = None
|
||||
self.address_type = None
|
||||
|
||||
def switch(self, an_input: str):
|
||||
"""Process and dispatch input
|
||||
@@ -73,7 +103,7 @@ class OnchainController:
|
||||
|
||||
# Help menu again
|
||||
if known_args.cmd == "?":
|
||||
print_help()
|
||||
self.print_help()
|
||||
return None
|
||||
|
||||
# Clear screen
|
||||
@@ -87,7 +117,7 @@ class OnchainController:
|
||||
|
||||
def call_help(self, *_):
|
||||
"""Process Help command"""
|
||||
print_help()
|
||||
self.print_help()
|
||||
|
||||
def call_q(self, _):
|
||||
"""Process Q command - quit the menu"""
|
||||
@@ -186,8 +216,8 @@ class OnchainController:
|
||||
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
"--address",
|
||||
dest="address",
|
||||
"--balance",
|
||||
dest="balance",
|
||||
action="store_true",
|
||||
help="Flag to show addresses of transaction",
|
||||
default=False,
|
||||
@@ -220,18 +250,631 @@ class OnchainController:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_address(self, other_args: List[str]):
|
||||
"""Process address command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="address",
|
||||
description="""
|
||||
Load address for further analysis. You can analyze account address, token address or transaction hash.
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
def print_help():
|
||||
"""Print help"""
|
||||
print("\nOnchain:")
|
||||
print(" cls clear screen")
|
||||
print(" ?/help show this menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("")
|
||||
print(" gwei check current eth gas fees")
|
||||
print(" whales check crypto wales transactions")
|
||||
print("")
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
action="store_true",
|
||||
help="Account address",
|
||||
dest="account",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
action="store_true",
|
||||
help="ERC20 token address",
|
||||
dest="token",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-tx",
|
||||
action="store_true",
|
||||
help="Transaction hash",
|
||||
dest="transaction",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--address",
|
||||
dest="address",
|
||||
help="Ethereum address",
|
||||
default=False,
|
||||
type=str,
|
||||
required="-h" not in other_args,
|
||||
)
|
||||
|
||||
try:
|
||||
if other_args:
|
||||
if not other_args[0][0] == "-":
|
||||
other_args.insert(0, "--address")
|
||||
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser:
|
||||
return
|
||||
|
||||
if len(ns_parser.address) not in [42, 66]:
|
||||
print(
|
||||
f"Couldn't load address {ns_parser.address}. "
|
||||
f"Token or account address should be 42 characters long. "
|
||||
f"Transaction hash should be 66 characters long\n"
|
||||
)
|
||||
return
|
||||
|
||||
if ns_parser.account:
|
||||
address_type = "account"
|
||||
elif ns_parser.token:
|
||||
address_type = "token"
|
||||
elif ns_parser.transaction:
|
||||
address_type = "tx"
|
||||
else:
|
||||
address_type = "account"
|
||||
|
||||
if len(ns_parser.address) == 66:
|
||||
address_type = "tx"
|
||||
|
||||
self.address = ns_parser.address
|
||||
self.address_type = address_type
|
||||
|
||||
print(f"Address loaded {self.address}\n")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_balance(self, other_args: List[str]):
|
||||
"""Process balance command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="balance",
|
||||
description="""
|
||||
Display info about tokens on given ethereum blockchain balance.
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--top",
|
||||
dest="top",
|
||||
type=check_positive,
|
||||
help="top N number records",
|
||||
default=10,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sort",
|
||||
dest="sortby",
|
||||
type=str,
|
||||
help="Sort by given column. Default: index",
|
||||
default="index",
|
||||
choices=[
|
||||
"index",
|
||||
"balance",
|
||||
"tokenName",
|
||||
"tokenSymbol",
|
||||
],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--descend",
|
||||
action="store_false",
|
||||
help="Flag to sort in descending order (lowest first)",
|
||||
dest="descend",
|
||||
default=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_address_info(
|
||||
top=ns_parser.top,
|
||||
sortby=ns_parser.sortby,
|
||||
descend=ns_parser.descend,
|
||||
address=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_hist(self, other_args: List[str]):
|
||||
"""Process hist command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="hist",
|
||||
description="""
|
||||
Display history for given ethereum blockchain balance.
|
||||
e.g. 0x3cD751E6b0078Be393132286c442345e5DC49699
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--top",
|
||||
dest="top",
|
||||
type=check_positive,
|
||||
help="top N number records",
|
||||
default=10,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sort",
|
||||
dest="sortby",
|
||||
type=str,
|
||||
help="Sort by given column. Default: timestamp",
|
||||
default="timestamp",
|
||||
choices=["timestamp", "transactionHash", "token", "value"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--descend",
|
||||
action="store_false",
|
||||
help="Flag to sort in descending order (lowest first)",
|
||||
dest="descend",
|
||||
default=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_address_history(
|
||||
top=ns_parser.top,
|
||||
sortby=ns_parser.sortby,
|
||||
descend=ns_parser.descend,
|
||||
address=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_holders(self, other_args: List[str]):
|
||||
"""Process holders command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="holders",
|
||||
description="""
|
||||
Display top ERC20 token holders: e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--top",
|
||||
dest="top",
|
||||
type=check_positive,
|
||||
help="top N number records",
|
||||
default=10,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sort",
|
||||
dest="sortby",
|
||||
type=str,
|
||||
help="Sort by given column. Default: share",
|
||||
default="share",
|
||||
choices=[
|
||||
"balance",
|
||||
"balance",
|
||||
"share",
|
||||
],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--descend",
|
||||
action="store_false",
|
||||
help="Flag to sort in descending order (lowest first)",
|
||||
dest="descend",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_top_token_holders(
|
||||
top=ns_parser.top,
|
||||
sortby=ns_parser.sortby,
|
||||
descend=ns_parser.descend,
|
||||
address=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_top(self, other_args: List[str]):
|
||||
"""Process top command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="top",
|
||||
description="""
|
||||
Display top ERC20 tokens.
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--top",
|
||||
dest="top",
|
||||
type=check_positive,
|
||||
help="top N number records",
|
||||
default=10,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sort",
|
||||
dest="sortby",
|
||||
type=str,
|
||||
help="Sort by given column. Default: rank",
|
||||
default="rank",
|
||||
choices=[
|
||||
"rank",
|
||||
"name",
|
||||
"symbol",
|
||||
"price",
|
||||
"txsCount",
|
||||
"transfersCount",
|
||||
"holdersCount",
|
||||
],
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--descend",
|
||||
action="store_false",
|
||||
help="Flag to sort in descending order (lowest first)",
|
||||
dest="descend",
|
||||
default=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser:
|
||||
return
|
||||
|
||||
ethplorer_view.display_top_tokens(
|
||||
top=ns_parser.top,
|
||||
sortby=ns_parser.sortby,
|
||||
descend=ns_parser.descend,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_info(self, other_args: List[str]):
|
||||
"""Process info command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="info",
|
||||
description="""
|
||||
Display info about ERC20 token. e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--social",
|
||||
action="store_false",
|
||||
help="Flag to show social media links",
|
||||
dest="social",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_token_info(
|
||||
social=ns_parser.social,
|
||||
address=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_th(self, other_args: List[str]):
|
||||
"""Process th command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="th",
|
||||
description="""
|
||||
Displays info about token history.
|
||||
e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--top",
|
||||
dest="top",
|
||||
type=check_positive,
|
||||
help="top N number records",
|
||||
default=10,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sort",
|
||||
dest="sortby",
|
||||
type=str,
|
||||
help="Sort by given column. Default: value",
|
||||
default="value",
|
||||
choices=[
|
||||
"value",
|
||||
],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--descend",
|
||||
action="store_false",
|
||||
help="Flag to sort in descending order (lowest first)",
|
||||
dest="descend",
|
||||
default=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--hash",
|
||||
action="store_false",
|
||||
help="Flag to show transaction hash",
|
||||
dest="hash",
|
||||
default=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_token_history(
|
||||
top=ns_parser.top,
|
||||
hash_=ns_parser.hash,
|
||||
sortby=ns_parser.sortby,
|
||||
descend=ns_parser.descend,
|
||||
address=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_tx(self, other_args: List[str]):
|
||||
"""Process tx command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="tx",
|
||||
description="""
|
||||
Display info ERC20 token transaction on ethereum blockchain.
|
||||
e.g. 0x9dc7b43ad4288c624fdd236b2ecb9f2b81c93e706b2ffd1d19b112c1df7849e6
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_tx_info(
|
||||
tx_hash=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def call_prices(self, other_args: List[str]):
|
||||
"""Process prices command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="prices",
|
||||
description="""
|
||||
"Display token historical prices. e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
|
||||
[Source: Ethplorer]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--top",
|
||||
dest="top",
|
||||
type=check_positive,
|
||||
help="top N number records",
|
||||
default=10,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sort",
|
||||
dest="sortby",
|
||||
type=str,
|
||||
help="Sort by given column. Default: date",
|
||||
default="date",
|
||||
choices=[
|
||||
"date",
|
||||
"cap",
|
||||
"volumeConverted",
|
||||
"open",
|
||||
"high",
|
||||
"close",
|
||||
"low",
|
||||
],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--descend",
|
||||
action="store_false",
|
||||
help="Flag to sort in descending order (lowest first)",
|
||||
dest="descend",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
help="Export dataframe data to csv,json,xlsx file",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if not ns_parser or not self.address:
|
||||
return
|
||||
|
||||
ethplorer_view.display_token_historical_prices(
|
||||
top=ns_parser.top,
|
||||
sortby=ns_parser.sortby,
|
||||
descend=ns_parser.descend,
|
||||
address=self.address,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def print_help(self):
|
||||
"""Print help"""
|
||||
help_text = """
|
||||
Onchain:
|
||||
cls clear screen
|
||||
?/help show this menu again
|
||||
q quit this menu, and shows back to main menu
|
||||
quit quit to abandon the program
|
||||
|
||||
gwei check current eth gas fees
|
||||
whales check crypto wales transactions
|
||||
"""
|
||||
help_text += f"\nEthereum address: {self.address if self.address else '?'}"
|
||||
help_text += (
|
||||
f"\nAddress type: {self.address_type if self.address_type else '?'}\n"
|
||||
)
|
||||
|
||||
help_text += """
|
||||
Ethereum:
|
||||
address load ethereum address of token, account or transaction
|
||||
top top ERC20 tokens"""
|
||||
|
||||
if self.address_type == "account":
|
||||
help_text += """
|
||||
balance check ethereum balance balance
|
||||
hist ethereum balance history (transactions)"""
|
||||
|
||||
if self.address_type == "token":
|
||||
help_text += """
|
||||
info ERC20 token info
|
||||
holders top ERC20 token holders
|
||||
th ERC20 token history
|
||||
prices ERC20 token historical prices"""
|
||||
|
||||
if self.address_type == "tx":
|
||||
help_text += """
|
||||
tx ethereum blockchain transaction info"""
|
||||
|
||||
print(help_text, "\n")
|
||||
|
||||
|
||||
def menu():
|
||||
|
||||
@@ -74,7 +74,7 @@ def get_whales_transactions(min_value: int = 800000, limit: int = 100) -> pd.Dat
|
||||
)
|
||||
|
||||
data["date"] = pd.to_datetime(data["timestamp"], unit="s")
|
||||
data.columns = [col.replace(".address", "") for col in data.columns]
|
||||
data.columns = [col.replace(".balance", "") for col in data.columns]
|
||||
data["to_address"] = data["to"].apply(
|
||||
lambda x: "\n".join(textwrap.wrap(x, width=45)) if isinstance(x, str) else x
|
||||
)
|
||||
|
||||
@@ -310,7 +310,7 @@ def get_contract_platform(platform_id: str = "eth-ethereum") -> pd.DataFrame:
|
||||
Returns
|
||||
-------
|
||||
pandas.DataFrame
|
||||
id, type, active, address
|
||||
id, type, active, balance
|
||||
"""
|
||||
|
||||
session = PaprikaSession()
|
||||
@@ -318,4 +318,4 @@ def get_contract_platform(platform_id: str = "eth-ethereum") -> pd.DataFrame:
|
||||
session.ENDPOINTS["contract_platform_addresses"].format(platform_id)
|
||||
)
|
||||
|
||||
return pd.DataFrame(contract_platforms)[["id", "type", "active", "address"]]
|
||||
return pd.DataFrame(contract_platforms)[["id", "type", "active", "balance"]]
|
||||
|
||||
@@ -1458,11 +1458,11 @@ Coinbase:
|
||||
description="""Gets all contract addresses for given platform.
|
||||
Provide platform id with -p/--platform parameter
|
||||
You can display only top N number of smart contracts with --top parameter.
|
||||
You can sort data by id, type, active, address --sort parameter
|
||||
You can sort data by id, type, active, balance --sort parameter
|
||||
and also with --descend flag to sort descending.
|
||||
|
||||
Displays:
|
||||
id, type, active, address
|
||||
id, type, active, balance
|
||||
""",
|
||||
)
|
||||
|
||||
@@ -1492,7 +1492,7 @@ Coinbase:
|
||||
type=str,
|
||||
help="Sort by given column",
|
||||
default="id",
|
||||
choices=["id", "type", "active", "address"],
|
||||
choices=["id", "type", "active", "balance"],
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
|
||||
14
website/content/cryptocurrency/onchain/address/_index.md
vendored
Normal file
14
website/content/cryptocurrency/onchain/address/_index.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
```
|
||||
usage: address [-a] [-t] [-tx] [--address ADDRESS] [-h]
|
||||
```
|
||||
|
||||
Load address for further analysis. You can analyze account address, token address or transaction hash. [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-a Account address (default: False)
|
||||
-t ERC20 token address (default: False)
|
||||
-tx Transaction hash (default: False)
|
||||
--address ADDRESS Ethereum address (default: False)
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
18
website/content/cryptocurrency/onchain/balance/_index.md
vendored
Normal file
18
website/content/cryptocurrency/onchain/balance/_index.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
```
|
||||
usage: balance [-t TOP] [-s {index,balance,tokenName,tokenSymbol}] [--descend] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display info about tokens on given ethereum blockchain address. [Source:
|
||||
Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-t TOP, --top TOP top N number records (default: 10)
|
||||
-s {index,balance,tokenName,tokenSymbol}, --sort {index,balance,tokenName,tokenSymbol}
|
||||
Sort by given column. Default: index (default: index)
|
||||
--descend Flag to sort in descending order (lowest first) (default: True)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
|
||||
```
|
||||
18
website/content/cryptocurrency/onchain/hist/_index.md
vendored
Normal file
18
website/content/cryptocurrency/onchain/hist/_index.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
```
|
||||
usage: hist [-t TOP] [-s {timestamp,transactionHash,token,value}] [--descend] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display history for given ethereum blockchain address. e.g.
|
||||
0x3cD751E6b0078Be393132286c442345e5DC49699 [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-t TOP, --top TOP top N number records (default: 10)
|
||||
-s {timestamp,transactionHash,token,value}, --sort {timestamp,transactionHash,token,value}
|
||||
Sort by given column. Default: timestamp (default: timestamp)
|
||||
--descend Flag to sort in descending order (lowest first) (default: True)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
|
||||
```
|
||||
16
website/content/cryptocurrency/onchain/holders/_index.md
vendored
Normal file
16
website/content/cryptocurrency/onchain/holders/_index.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
```
|
||||
usage: holders [-t TOP] [-s {balance,balance,share}] [--descend] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display top ERC20 token holders: e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-t TOP, --top TOP top N number records (default: 10)
|
||||
-s {balance,balance,share}, --sort {balance,balance,share}
|
||||
Sort by given column. Default: share (default: share)
|
||||
--descend Flag to sort in descending order (lowest first) (default: False)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
13
website/content/cryptocurrency/onchain/info/_index.md
vendored
Normal file
13
website/content/cryptocurrency/onchain/info/_index.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
```
|
||||
usage: info [--social] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display info about ERC20 token. e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 [Source: Ethplorer]
|
||||
```
|
||||
optional arguments:
|
||||
--social Flag to show social media links (default: False)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
|
||||
```
|
||||
16
website/content/cryptocurrency/onchain/prices/_index.md
vendored
Normal file
16
website/content/cryptocurrency/onchain/prices/_index.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
```
|
||||
usage: prices [-t TOP] [-s {date,cap,volumeConverted,open,high,close,low}] [--descend] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display token historical prices. e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-t TOP, --top TOP top N number records (default: 10)
|
||||
-s {date,cap,volumeConverted,open,high,close,low}, --sort {date,cap,volumeConverted,open,high,close,low}
|
||||
Sort by given column. Default: date (default: date)
|
||||
--descend Flag to sort in descending order (lowest first) (default: False)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
17
website/content/cryptocurrency/onchain/th/_index.md
vendored
Normal file
17
website/content/cryptocurrency/onchain/th/_index.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
```
|
||||
usage: th [-t TOP] [-s {value}] [--descend] [--hash] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Displays info about token history. e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-t TOP, --top TOP top N number records (default: 10)
|
||||
-s {value}, --sort {value}
|
||||
Sort by given column. Default: value (default: value)
|
||||
--descend Flag to sort in descending order (lowest first) (default: True)
|
||||
--hash Flag to show transaction hash (default: True)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
20
website/content/cryptocurrency/onchain/top/_index.md
vendored
Normal file
20
website/content/cryptocurrency/onchain/top/_index.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
```
|
||||
usage: top [-t TOP]
|
||||
[-s {rank,name,symbol,price,txsCount,transfersCount,holdersCount,address}]
|
||||
[--descend] [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display top ERC20 tokens. [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-t TOP, --top TOP top N number records (default: 10)
|
||||
-s {rank,name,symbol,price,txsCount,transfersCount,holdersCount,address}, --sort {rank,name,symbol,price,txsCount,transfersCount,holdersCount,address}
|
||||
Sort by given column. Default: rank (default: rank)
|
||||
--descend Flag to sort in descending order (lowest first)
|
||||
(default: True)
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default:
|
||||
)
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
12
website/content/cryptocurrency/onchain/tx/_index.md
vendored
Normal file
12
website/content/cryptocurrency/onchain/tx/_index.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
```
|
||||
usage: tx [--export {csv,json,xlsx}] [-h]
|
||||
```
|
||||
|
||||
Display info ERC20 token transaction on ethereum blockchain. e.g. 0x9dc7b43ad4288c624fdd236b2ecb9f2b81c93e706b2ffd1d19b112c1df7849e6 [Source: Ethplorer]
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
--export {csv,json,xlsx}
|
||||
Export dataframe data to csv,json,xlsx file (default: )
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
Reference in New Issue
Block a user