mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-21 23:18:13 +00:00
feat(common): add wallet info to cointool dump
This commit is contained in:
parent
08f463e5e8
commit
9261f2ffce
@ -123,5 +123,13 @@
|
||||
},
|
||||
"eth:WAN": {
|
||||
"Wanchain Wallet": "https://www.wanchain.org/getstarted/"
|
||||
},
|
||||
"eth:AUX": {
|
||||
"MyEtherWallet": null
|
||||
},
|
||||
"eth:XDC": {
|
||||
"MyCrypto": null,
|
||||
"MyEtherWallet": null,
|
||||
"XDC Wallet": "https://wallet.xinfin.network"
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ class SupportInfoItem(TypedDict):
|
||||
|
||||
SupportInfo = dict[str, SupportInfoItem]
|
||||
|
||||
WalletItems = dict[str, str]
|
||||
WalletInfo = dict[str, WalletItems]
|
||||
|
||||
|
||||
class Coin(TypedDict):
|
||||
# Necessary fields for BTC - from BTC_CHECKS
|
||||
@ -86,7 +89,7 @@ class Coin(TypedDict):
|
||||
|
||||
# Other fields optionally coming from JSON
|
||||
links: dict[str, str]
|
||||
wallet: dict[str, str]
|
||||
wallet: WalletItems
|
||||
curve: str
|
||||
decimals: int
|
||||
|
||||
@ -540,6 +543,115 @@ def support_info(coins: Iterable[Coin] | CoinsInfo | dict[str, Coin]) -> Support
|
||||
return support
|
||||
|
||||
|
||||
# ====== wallet info ======
|
||||
|
||||
WALLET_SUITE = {"Trezor Suite": "https://suite.trezor.io"}
|
||||
WALLET_NEM = {"Nano Wallet": "https://nemplatform.com/wallets/#desktop"}
|
||||
WALLETS_ETH_3RDPARTY = {
|
||||
"MyEtherWallet": "https://www.myetherwallet.com",
|
||||
"MyCrypto": "https://mycrypto.com",
|
||||
}
|
||||
|
||||
|
||||
def get_wallet_data() -> WalletInfo:
|
||||
"""Get wallet data from `wallets.json`."""
|
||||
return load_json("wallets.json")
|
||||
|
||||
|
||||
def _suite_support(coin: Coin, support: SupportInfoItem) -> bool:
|
||||
"""Check the "suite" support property.
|
||||
If set, check that at least one of the backends run on trezor.io.
|
||||
If yes, assume we support the coin in our wallet.
|
||||
Otherwise it's probably working with a custom backend, which means don't
|
||||
link to our wallet.
|
||||
"""
|
||||
if not support["suite"]:
|
||||
return False
|
||||
return any(".trezor.io" in url for url in coin["blockbook"])
|
||||
|
||||
|
||||
def wallet_info_single(
|
||||
support_data: SupportInfo,
|
||||
eth_networks_support_data: SupportInfo,
|
||||
wallet_data: WalletInfo,
|
||||
coin: Coin,
|
||||
) -> WalletItems:
|
||||
"""Adds together a dict of all wallets for a coin."""
|
||||
wallets: WalletItems = {}
|
||||
|
||||
key = coin["key"]
|
||||
|
||||
# Add wallets from the coin itself
|
||||
# (usually not there, only for the `misc` category)
|
||||
wallets.update(coin.get("wallet", {}))
|
||||
|
||||
# Each coin category has different further logic
|
||||
if key.startswith("bitcoin:"):
|
||||
if _suite_support(coin, support_data[key]):
|
||||
wallets.update(WALLET_SUITE)
|
||||
elif key.startswith("eth:"):
|
||||
if support_data[key]["suite"]:
|
||||
wallets.update(WALLET_SUITE)
|
||||
else:
|
||||
wallets.update(WALLETS_ETH_3RDPARTY)
|
||||
elif key.startswith("erc20:"):
|
||||
if eth_networks_support_data[coin["chain"]]["suite"]:
|
||||
wallets.update(WALLET_SUITE)
|
||||
else:
|
||||
wallets.update(WALLETS_ETH_3RDPARTY)
|
||||
elif key.startswith("nem:"):
|
||||
wallets.update(WALLET_NEM)
|
||||
elif key.startswith("misc:"):
|
||||
pass # no special logic here
|
||||
else:
|
||||
raise ValueError(f"Unknown coin category: {key}")
|
||||
|
||||
# Add wallets from `wallets.json`
|
||||
# This must come last as it offers the ability to override existing wallets
|
||||
# (for example with `"MyEtherWallet": null` we delete the MyEtherWallet from the coin)
|
||||
wallets.update(wallet_data.get(key, {}))
|
||||
|
||||
# Removing potentially disabled wallets from the last step
|
||||
wallets = {name: url for name, url in wallets.items() if url}
|
||||
|
||||
return wallets
|
||||
|
||||
|
||||
def wallet_info(coins: Iterable[Coin] | CoinsInfo | dict[str, Coin]) -> WalletInfo:
|
||||
"""Generate Trezor wallet information.
|
||||
|
||||
Takes a collection of coins and generates a WalletItems entry for each.
|
||||
The WalletItems is a dict with keys being the names of the wallets and
|
||||
values being the URLs to those - same format as in `wallets.json`.
|
||||
|
||||
The `coins` argument can be a `CoinsInfo` object, a list or a dict of
|
||||
coin items.
|
||||
|
||||
Wallet information is taken from `wallets.json`.
|
||||
"""
|
||||
if isinstance(coins, CoinsInfo):
|
||||
coins = coins.as_list()
|
||||
elif isinstance(coins, dict):
|
||||
coins = coins.values()
|
||||
|
||||
support_data = support_info(coins)
|
||||
wallet_data = get_wallet_data()
|
||||
|
||||
# Needed to find out suitable wallets for all the erc20 coins (Suite vs 3rd party)
|
||||
eth_networks = [coin for coin in coins if coin["key"].startswith("eth:")]
|
||||
eth_networks_support_data = {
|
||||
n["chain"]: support_data[n["key"]] for n in eth_networks
|
||||
}
|
||||
|
||||
wallet: WalletInfo = {}
|
||||
for coin in coins:
|
||||
wallet[coin["key"]] = wallet_info_single(
|
||||
support_data, eth_networks_support_data, wallet_data, coin
|
||||
)
|
||||
|
||||
return wallet
|
||||
|
||||
|
||||
# ====== data cleanup functions ======
|
||||
|
||||
|
||||
|
@ -711,6 +711,7 @@ device_choice = click.Choice(["connect", "suite", "trezor1", "trezor2"])
|
||||
# fmt: off
|
||||
@click.option("-o", "--outfile", type=click.File(mode="w"), default="-")
|
||||
@click.option("-s/-S", "--support/--no-support", default=True, help="Include support data for each coin")
|
||||
@click.option("-w/-W", "--wallet/--no-wallet", default=True, help="Include wallet data for each coin")
|
||||
@click.option("-p", "--pretty", is_flag=True, help="Generate nicely formatted JSON")
|
||||
@click.option("-l", "--list", "flat_list", is_flag=True, help="Output a flat list of coins")
|
||||
@click.option("-i", "--include", metavar="FIELD", multiple=True, help="Include only these fields (-i shortcut -i name)")
|
||||
@ -726,6 +727,7 @@ device_choice = click.Choice(["connect", "suite", "trezor1", "trezor2"])
|
||||
def dump(
|
||||
outfile: TextIO,
|
||||
support: bool,
|
||||
wallet: bool,
|
||||
pretty: bool,
|
||||
flat_list: bool,
|
||||
include: tuple[str, ...],
|
||||
@ -770,6 +772,9 @@ def dump(
|
||||
Also devices can be used as filters. For example to find out which coins are
|
||||
supported in Suite and connect but not on Trezor 1, it is possible to say
|
||||
'-d suite -d connect -D trezor1'.
|
||||
|
||||
Includes even the wallet data, unless turned off by '-W'.
|
||||
These can be filtered by using '-f', for example `-f 'wallet=*exodus*'` (* are necessary)
|
||||
"""
|
||||
if exclude_tokens:
|
||||
exclude_type += ("erc20",)
|
||||
@ -786,6 +791,7 @@ def dump(
|
||||
# getting initial info
|
||||
coins = coin_info.coin_info()
|
||||
support_info = coin_info.support_info(coins.as_list())
|
||||
wallet_info = coin_info.wallet_info(coins)
|
||||
|
||||
# optionally adding support info
|
||||
if support:
|
||||
@ -793,6 +799,12 @@ def dump(
|
||||
for coin in category:
|
||||
coin["support"] = support_info[coin["key"]]
|
||||
|
||||
# optionally adding wallet info
|
||||
if wallet:
|
||||
for category in coins.values():
|
||||
for coin in category:
|
||||
coin["wallet"] = wallet_info[coin["key"]]
|
||||
|
||||
# filter types
|
||||
if include_type:
|
||||
coins_dict = {k: v for k, v in coins.items() if k in include_type}
|
||||
|
Loading…
Reference in New Issue
Block a user