mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +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": {
|
"eth:WAN": {
|
||||||
"Wanchain Wallet": "https://www.wanchain.org/getstarted/"
|
"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]
|
SupportInfo = dict[str, SupportInfoItem]
|
||||||
|
|
||||||
|
WalletItems = dict[str, str]
|
||||||
|
WalletInfo = dict[str, WalletItems]
|
||||||
|
|
||||||
|
|
||||||
class Coin(TypedDict):
|
class Coin(TypedDict):
|
||||||
# Necessary fields for BTC - from BTC_CHECKS
|
# Necessary fields for BTC - from BTC_CHECKS
|
||||||
@ -86,7 +89,7 @@ class Coin(TypedDict):
|
|||||||
|
|
||||||
# Other fields optionally coming from JSON
|
# Other fields optionally coming from JSON
|
||||||
links: dict[str, str]
|
links: dict[str, str]
|
||||||
wallet: dict[str, str]
|
wallet: WalletItems
|
||||||
curve: str
|
curve: str
|
||||||
decimals: int
|
decimals: int
|
||||||
|
|
||||||
@ -540,6 +543,115 @@ def support_info(coins: Iterable[Coin] | CoinsInfo | dict[str, Coin]) -> Support
|
|||||||
return 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 ======
|
# ====== data cleanup functions ======
|
||||||
|
|
||||||
|
|
||||||
|
@ -711,6 +711,7 @@ device_choice = click.Choice(["connect", "suite", "trezor1", "trezor2"])
|
|||||||
# fmt: off
|
# fmt: off
|
||||||
@click.option("-o", "--outfile", type=click.File(mode="w"), default="-")
|
@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("-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("-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("-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)")
|
@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(
|
def dump(
|
||||||
outfile: TextIO,
|
outfile: TextIO,
|
||||||
support: bool,
|
support: bool,
|
||||||
|
wallet: bool,
|
||||||
pretty: bool,
|
pretty: bool,
|
||||||
flat_list: bool,
|
flat_list: bool,
|
||||||
include: tuple[str, ...],
|
include: tuple[str, ...],
|
||||||
@ -770,6 +772,9 @@ def dump(
|
|||||||
Also devices can be used as filters. For example to find out which coins are
|
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
|
supported in Suite and connect but not on Trezor 1, it is possible to say
|
||||||
'-d suite -d connect -D trezor1'.
|
'-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:
|
if exclude_tokens:
|
||||||
exclude_type += ("erc20",)
|
exclude_type += ("erc20",)
|
||||||
@ -786,6 +791,7 @@ def dump(
|
|||||||
# getting initial info
|
# getting initial info
|
||||||
coins = coin_info.coin_info()
|
coins = coin_info.coin_info()
|
||||||
support_info = coin_info.support_info(coins.as_list())
|
support_info = coin_info.support_info(coins.as_list())
|
||||||
|
wallet_info = coin_info.wallet_info(coins)
|
||||||
|
|
||||||
# optionally adding support info
|
# optionally adding support info
|
||||||
if support:
|
if support:
|
||||||
@ -793,6 +799,12 @@ def dump(
|
|||||||
for coin in category:
|
for coin in category:
|
||||||
coin["support"] = support_info[coin["key"]]
|
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
|
# filter types
|
||||||
if include_type:
|
if include_type:
|
||||||
coins_dict = {k: v for k, v in coins.items() if k in 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