mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-28 21:19:03 +00:00
tools: coin_defs renamed to coin_info and interface
improved a little
This commit is contained in:
parent
1e032d4da5
commit
b5443af4c5
@ -8,7 +8,7 @@ import glob
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
import coin_defs
|
import coin_info
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import mako
|
import mako
|
||||||
@ -25,10 +25,13 @@ except ImportError:
|
|||||||
requests = None
|
requests = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
import binascii
|
||||||
|
import struct
|
||||||
|
import zlib
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
import ed25519
|
import ed25519
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from trezorlib.protobuf import dump_message
|
from trezorlib import protobuf
|
||||||
from coindef import CoinDef
|
from coindef import CoinDef
|
||||||
|
|
||||||
CAN_BUILD_DEFS = True
|
CAN_BUILD_DEFS = True
|
||||||
@ -36,7 +39,7 @@ except ImportError:
|
|||||||
CAN_BUILD_DEFS = False
|
CAN_BUILD_DEFS = False
|
||||||
|
|
||||||
|
|
||||||
# ======= Jinja2 management ======
|
# ======= Mako management ======
|
||||||
|
|
||||||
|
|
||||||
def c_str_filter(b):
|
def c_str_filter(b):
|
||||||
@ -70,26 +73,36 @@ def render_file(filename, coins, support_info):
|
|||||||
# ====== validation functions ======
|
# ====== validation functions ======
|
||||||
|
|
||||||
|
|
||||||
def check_support(defs, support_data):
|
def check_support(defs, support_data, fail_missing=False):
|
||||||
check_passed = True
|
check_passed = True
|
||||||
|
coin_list = defs.as_list()
|
||||||
|
coin_names = {coin["key"]: coin["name"] for coin in coin_list}
|
||||||
|
|
||||||
|
def coin_name(key):
|
||||||
|
if key in coin_names:
|
||||||
|
return "{} ({})".format(key, coin_names[key])
|
||||||
|
else:
|
||||||
|
return "{} <unknown key>".format(key)
|
||||||
|
|
||||||
for key, support in support_data.items():
|
for key, support in support_data.items():
|
||||||
errors = coin_defs.validate_support(support)
|
errors = coin_info.validate_support(support)
|
||||||
if errors:
|
if errors:
|
||||||
check_passed = False
|
check_passed = False
|
||||||
print("ERR:", "invalid definition for", key)
|
print("ERR:", "invalid definition for", coin_name(key))
|
||||||
print("\n".join(errors))
|
print("\n".join(errors))
|
||||||
|
|
||||||
expected_coins = set(coin["key"] for coin in defs["coins"] + defs["misc"])
|
expected_coins = set(coin["key"] for coin in defs.coins + defs.misc)
|
||||||
|
|
||||||
# detect missing support info for expected
|
# detect missing support info for expected
|
||||||
for coin in expected_coins:
|
for coin in expected_coins:
|
||||||
if coin not in support_data:
|
if coin not in support_data:
|
||||||
check_passed = False
|
if fail_missing:
|
||||||
print("ERR: Missing support info for", coin)
|
check_passed = False
|
||||||
|
print("ERR: Missing support info for", coin_name(coin))
|
||||||
|
else:
|
||||||
|
print("WARN: Missing support info for", coin_name(coin))
|
||||||
|
|
||||||
# detect non-matching support info
|
# detect non-matching support info
|
||||||
coin_list = sum(defs.values(), [])
|
|
||||||
coin_set = set(coin["key"] for coin in coin_list)
|
coin_set = set(coin["key"] for coin in coin_list)
|
||||||
for key in support_data:
|
for key in support_data:
|
||||||
# detect non-matching support info
|
# detect non-matching support info
|
||||||
@ -97,9 +110,9 @@ def check_support(defs, support_data):
|
|||||||
check_passed = False
|
check_passed = False
|
||||||
print("ERR: Support info found for unknown coin", key)
|
print("ERR: Support info found for unknown coin", key)
|
||||||
|
|
||||||
# detect override - info only, doesn't fail check
|
# detect override - doesn't fail check
|
||||||
if key not in expected_coins:
|
if key not in expected_coins:
|
||||||
print("INFO: Override present for coin", key)
|
print("INFO: Override present for coin", coin_name(key))
|
||||||
|
|
||||||
return check_passed
|
return check_passed
|
||||||
|
|
||||||
@ -108,13 +121,13 @@ def check_btc(coins):
|
|||||||
check_passed = True
|
check_passed = True
|
||||||
|
|
||||||
for coin in coins:
|
for coin in coins:
|
||||||
errors = coin_defs.validate_btc(coin)
|
errors = coin_info.validate_btc(coin)
|
||||||
if errors:
|
if errors:
|
||||||
check_passed = False
|
check_passed = False
|
||||||
print("ERR:", "invalid definition for", coin["name"])
|
print("ERR:", "invalid definition for", coin["name"])
|
||||||
print("\n".join(errors))
|
print("\n".join(errors))
|
||||||
|
|
||||||
collisions = coin_defs.find_address_collisions(coins)
|
collisions = coin_info.find_address_collisions(coins)
|
||||||
# warning only
|
# warning only
|
||||||
for key, dups in collisions.items():
|
for key, dups in collisions.items():
|
||||||
if dups:
|
if dups:
|
||||||
@ -135,7 +148,7 @@ def check_backends(coins):
|
|||||||
for backend in backends:
|
for backend in backends:
|
||||||
print("checking", backend, "... ", end="", flush=True)
|
print("checking", backend, "... ", end="", flush=True)
|
||||||
try:
|
try:
|
||||||
j = requests.get(backend + "/block-index/0").json()
|
j = requests.get(backend + "/api/block-index/0").json()
|
||||||
if j["blockHash"] != genesis_block:
|
if j["blockHash"] != genesis_block:
|
||||||
raise RuntimeError("genesis block mismatch")
|
raise RuntimeError("genesis block mismatch")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -146,6 +159,59 @@ def check_backends(coins):
|
|||||||
return check_passed
|
return check_passed
|
||||||
|
|
||||||
|
|
||||||
|
# ====== coindefs generators ======
|
||||||
|
|
||||||
|
|
||||||
|
def convert_icon(icon):
|
||||||
|
"""Convert PIL icon to TOIF format"""
|
||||||
|
# TODO: move this to python-trezor at some point
|
||||||
|
DIM = 32
|
||||||
|
icon = icon.resize((DIM, DIM), Image.LANCZOS)
|
||||||
|
# remove alpha channel, replace with black
|
||||||
|
bg = Image.new("RGBA", icon.size, (0, 0, 0, 255))
|
||||||
|
icon = Image.alpha_composite(bg, icon)
|
||||||
|
# process pixels
|
||||||
|
pix = icon.load()
|
||||||
|
data = bytes()
|
||||||
|
for y in range(DIM):
|
||||||
|
for x in range(DIM):
|
||||||
|
r, g, b, _ = pix[x, y]
|
||||||
|
c = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)
|
||||||
|
data += struct.pack(">H", c)
|
||||||
|
z = zlib.compressobj(level=9, wbits=10)
|
||||||
|
zdata = z.compress(data) + z.flush()
|
||||||
|
zdata = zdata[2:-4] # strip header and checksum
|
||||||
|
return zdata
|
||||||
|
|
||||||
|
|
||||||
|
def coindef_from_dict(coin):
|
||||||
|
proto = CoinDef()
|
||||||
|
for fname, _, fflags in CoinDef.FIELDS.values():
|
||||||
|
val = coin.get(fname)
|
||||||
|
if val is None and fflags & protobuf.FLAG_REPEATED:
|
||||||
|
val = []
|
||||||
|
elif fname == "signed_message_header":
|
||||||
|
val = val.encode("utf-8")
|
||||||
|
elif fname == "hash_genesis_block":
|
||||||
|
val = binascii.unhexlify(val)
|
||||||
|
setattr(proto, fname, val)
|
||||||
|
|
||||||
|
return proto
|
||||||
|
|
||||||
|
|
||||||
|
def serialize_coindef(proto, icon):
|
||||||
|
proto.icon = icon
|
||||||
|
buf = io.BytesIO()
|
||||||
|
protobuf.dump_message(buf, proto)
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def sign(data):
|
||||||
|
h = sha256(data).digest()
|
||||||
|
sign_key = ed25519.SigningKey(b"A" * 32)
|
||||||
|
return sign_key.sign(h)
|
||||||
|
|
||||||
|
|
||||||
# ====== click command handlers ======
|
# ====== click command handlers ======
|
||||||
|
|
||||||
|
|
||||||
@ -155,12 +221,17 @@ def cli():
|
|||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
|
@click.option(
|
||||||
|
"--check-missing-support/--no-check-missing-support",
|
||||||
|
"-s",
|
||||||
|
help="Fail if support info for a coin is missing",
|
||||||
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--backend-check/--no-backend-check",
|
"--backend-check/--no-backend-check",
|
||||||
"-b",
|
"-b",
|
||||||
help="Also check blockbook/bitcore responses",
|
help="Also check blockbook/bitcore responses",
|
||||||
)
|
)
|
||||||
def check(backend_check):
|
def check(check_missing_support, backend_check):
|
||||||
"""Validate coin definitions.
|
"""Validate coin definitions.
|
||||||
|
|
||||||
Checks that every btc-like coin is properly filled out, reports address collisions
|
Checks that every btc-like coin is properly filled out, reports address collisions
|
||||||
@ -169,20 +240,21 @@ def check(backend_check):
|
|||||||
if backend_check and requests is None:
|
if backend_check and requests is None:
|
||||||
raise click.ClickException("You must install requests for backend check")
|
raise click.ClickException("You must install requests for backend check")
|
||||||
|
|
||||||
defs = coin_defs.get_all()
|
defs = coin_info.get_all()
|
||||||
all_checks_passed = True
|
all_checks_passed = True
|
||||||
|
|
||||||
print("Checking BTC-like coins...")
|
print("Checking BTC-like coins...")
|
||||||
if not check_btc(defs["coins"]):
|
if not check_btc(defs.coins):
|
||||||
all_checks_passed = False
|
all_checks_passed = False
|
||||||
|
|
||||||
print("Checking support data...")
|
print("Checking support data...")
|
||||||
if not check_support(defs, coin_defs.get_support_data()):
|
support_data = coin_info.get_support_data()
|
||||||
|
if not check_support(defs, support_data, fail_missing=check_missing_support):
|
||||||
all_checks_passed = False
|
all_checks_passed = False
|
||||||
|
|
||||||
if backend_check:
|
if backend_check:
|
||||||
print("Checking backend responses...")
|
print("Checking backend responses...")
|
||||||
if not check_backends(defs["coins"]):
|
if not check_backends(defs.coins):
|
||||||
all_checks_passed = False
|
all_checks_passed = False
|
||||||
|
|
||||||
if not all_checks_passed:
|
if not all_checks_passed:
|
||||||
@ -196,9 +268,8 @@ def check(backend_check):
|
|||||||
@click.option("-o", "--outfile", type=click.File(mode="w"), default="./coins.json")
|
@click.option("-o", "--outfile", type=click.File(mode="w"), default="./coins.json")
|
||||||
def coins_json(outfile):
|
def coins_json(outfile):
|
||||||
"""Generate coins.json for consumption in python-trezor and Connect/Wallet"""
|
"""Generate coins.json for consumption in python-trezor and Connect/Wallet"""
|
||||||
defs = coin_defs.get_all()
|
coins = coin_info.get_all().coins
|
||||||
coins = defs["coins"]
|
support_info = coin_info.support_info(coins)
|
||||||
support_info = coin_defs.support_info(coins)
|
|
||||||
by_name = {}
|
by_name = {}
|
||||||
for coin in coins:
|
for coin in coins:
|
||||||
coin["support"] = support_info[coin["key"]]
|
coin["support"] = support_info[coin["key"]]
|
||||||
@ -206,6 +277,30 @@ def coins_json(outfile):
|
|||||||
|
|
||||||
with outfile:
|
with outfile:
|
||||||
json.dump(by_name, outfile, indent=4, sort_keys=True)
|
json.dump(by_name, outfile, indent=4, sort_keys=True)
|
||||||
|
outfile.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@click.option("-o", "--outfile", type=click.File(mode="w"), default="./coindefs.json")
|
||||||
|
def coindefs(outfile):
|
||||||
|
"""Generate signed coin definitions for python-trezor and others
|
||||||
|
|
||||||
|
This is currently unused but should enable us to add new coins without having to
|
||||||
|
update firmware.
|
||||||
|
"""
|
||||||
|
coins = coin_info.get_all().coins
|
||||||
|
coindefs = {}
|
||||||
|
for coin in coins:
|
||||||
|
key = coin["key"]
|
||||||
|
icon = Image.open(coin["icon"])
|
||||||
|
ser = serialize_coindef(coindef_from_dict(coin), convert_icon(icon))
|
||||||
|
sig = sign(ser)
|
||||||
|
definition = binascii.hexlify(sig + ser).decode("ascii")
|
||||||
|
coindefs[key] = definition
|
||||||
|
|
||||||
|
with outfile:
|
||||||
|
json.dump(coindefs, outfile, indent=4, sort_keys=True)
|
||||||
|
outfile.write("\n")
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -236,10 +331,9 @@ def render(paths):
|
|||||||
else:
|
else:
|
||||||
files.append(path)
|
files.append(path)
|
||||||
|
|
||||||
defs = coin_defs.get_all()
|
defs = coin_info.get_all()
|
||||||
all_coins = sum(defs.values(), [])
|
versions = coin_info.latest_releases()
|
||||||
versions = coin_defs.latest_releases()
|
support_info = coin_info.support_info(defs, erc20_versions=versions)
|
||||||
support_info = coin_defs.support_info(all_coins, erc20_versions=versions)
|
|
||||||
|
|
||||||
# munch dicts - make them attribute-accessable
|
# munch dicts - make them attribute-accessable
|
||||||
for key, value in defs.items():
|
for key, value in defs.items():
|
||||||
|
@ -30,6 +30,35 @@ def load_json(*path):
|
|||||||
return json.load(f, object_pairs_hook=OrderedDict)
|
return json.load(f, object_pairs_hook=OrderedDict)
|
||||||
|
|
||||||
|
|
||||||
|
# ====== CoinsInfo ======
|
||||||
|
|
||||||
|
|
||||||
|
class CoinsInfo(dict):
|
||||||
|
"""Collection of information about all known kinds of coins.
|
||||||
|
|
||||||
|
It contains the following lists:
|
||||||
|
`coins` for btc-like coins,
|
||||||
|
`eth` for ethereum networks,
|
||||||
|
`erc20` for ERC20 tokens,
|
||||||
|
`nem` for NEM mosaics,
|
||||||
|
`misc` for other networks.
|
||||||
|
|
||||||
|
Accessible as a dict or by attribute: `info["coins"] == info.coins`
|
||||||
|
"""
|
||||||
|
|
||||||
|
def as_list(self):
|
||||||
|
return sum(self.values(), [])
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
return {coin["key"]: coin for coin in self.as_list()}
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
if attr in self:
|
||||||
|
return self[attr]
|
||||||
|
else:
|
||||||
|
raise AttributeError(attr)
|
||||||
|
|
||||||
|
|
||||||
# ====== coin validation ======
|
# ====== coin validation ======
|
||||||
|
|
||||||
|
|
||||||
@ -186,6 +215,7 @@ def _load_btc_coins():
|
|||||||
name=coin["coin_name"],
|
name=coin["coin_name"],
|
||||||
shortcut=coin["coin_shortcut"],
|
shortcut=coin["coin_shortcut"],
|
||||||
key="coin:{}".format(coin["coin_shortcut"]),
|
key="coin:{}".format(coin["coin_shortcut"]),
|
||||||
|
icon=filename.replace(".json", ".png"),
|
||||||
)
|
)
|
||||||
coins.append(coin)
|
coins.append(coin)
|
||||||
|
|
||||||
@ -324,11 +354,14 @@ def support_info_erc20(coins, versions):
|
|||||||
def support_info(coins, erc20_versions=None, skip_missing=False):
|
def support_info(coins, erc20_versions=None, skip_missing=False):
|
||||||
"""Generate Trezor support information.
|
"""Generate Trezor support information.
|
||||||
|
|
||||||
Takes a dict of coins and generates a support-info entry for each.
|
Takes a collection of coins and generates a support-info entry for each.
|
||||||
The support-info is a dict with a number of known keys:
|
The support-info is a dict with a number of known keys:
|
||||||
`trezor1`, `trezor2`, `webwallet`, `connect`. An optional `other` entry
|
`trezor1`, `trezor2`, `webwallet`, `connect`. An optional `other` entry
|
||||||
is a dict of name-url pairs for third-party software.
|
is a dict of name-url pairs for third-party software.
|
||||||
|
|
||||||
|
The `coins` argument can be a `CoinsInfo` object, a list or a dict of
|
||||||
|
coin items.
|
||||||
|
|
||||||
For btc-like coins and misc networks, this is taken from `support.json`.
|
For btc-like coins and misc networks, this is taken from `support.json`.
|
||||||
For NEM mosaics and ethereum networks, the support is presumed to be "yes"
|
For NEM mosaics and ethereum networks, the support is presumed to be "yes"
|
||||||
for both Trezors. Webwallet and Connect info is not filled out.
|
for both Trezors. Webwallet and Connect info is not filled out.
|
||||||
@ -346,6 +379,11 @@ def support_info(coins, erc20_versions=None, skip_missing=False):
|
|||||||
and a warning emitted. "No support information" means that the coin is not
|
and a warning emitted. "No support information" means that the coin is not
|
||||||
listed in `support.json` and we have no heuristic to determine the support.
|
listed in `support.json` and we have no heuristic to determine the support.
|
||||||
"""
|
"""
|
||||||
|
if isinstance(coins, CoinsInfo):
|
||||||
|
coins = coins.as_list()
|
||||||
|
elif isinstance(coins, dict):
|
||||||
|
coins = coins.values()
|
||||||
|
|
||||||
support_data = get_support_data()
|
support_data = get_support_data()
|
||||||
support = {}
|
support = {}
|
||||||
for coin in coins:
|
for coin in coins:
|
||||||
@ -428,6 +466,10 @@ def _filter_duplicate_shortcuts(coins):
|
|||||||
retained_coins = OrderedDict()
|
retained_coins = OrderedDict()
|
||||||
|
|
||||||
for coin in coins:
|
for coin in coins:
|
||||||
|
if "Testnet" in coin["name"] and coin["shortcut"] == "tETH":
|
||||||
|
# special case for Ethereum testnets
|
||||||
|
continue
|
||||||
|
|
||||||
key = coin["shortcut"]
|
key = coin["shortcut"]
|
||||||
if key in dup_keys:
|
if key in dup_keys:
|
||||||
pass
|
pass
|
||||||
@ -458,7 +500,7 @@ def get_all():
|
|||||||
`nem` for NEM mosaics,
|
`nem` for NEM mosaics,
|
||||||
`misc` for other networks.
|
`misc` for other networks.
|
||||||
"""
|
"""
|
||||||
all_coins = dict(
|
all_coins = CoinsInfo(
|
||||||
coins=_load_btc_coins(),
|
coins=_load_btc_coins(),
|
||||||
eth=_load_ethereum_networks(),
|
eth=_load_ethereum_networks(),
|
||||||
erc20=_load_erc20_tokens(),
|
erc20=_load_erc20_tokens(),
|
||||||
@ -476,22 +518,13 @@ def get_all():
|
|||||||
coins.sort(key=lambda c: c["key"].upper())
|
coins.sort(key=lambda c: c["key"].upper())
|
||||||
|
|
||||||
_ensure_mandatory_values(coins)
|
_ensure_mandatory_values(coins)
|
||||||
if k != "eth":
|
dup_keys = _filter_duplicate_shortcuts(coins)
|
||||||
dup_keys = _filter_duplicate_shortcuts(coins)
|
if dup_keys:
|
||||||
if dup_keys:
|
if k == "erc20":
|
||||||
log.warning(
|
severity = logging.INFO
|
||||||
"{}: removing duplicate symbols: {}".format(k, ", ".join(dup_keys))
|
else:
|
||||||
)
|
severity = logging.WARNING
|
||||||
|
dup_str = ", ".join(dup_keys)
|
||||||
|
log.log(severity, "{}: removing duplicate symbols: {}".format(k, dup_str))
|
||||||
|
|
||||||
return all_coins
|
return all_coins
|
||||||
|
|
||||||
|
|
||||||
def get_list():
|
|
||||||
"""Return all definitions as a single list of coins."""
|
|
||||||
all_coins = get_all()
|
|
||||||
return sum(all_coins.values(), [])
|
|
||||||
|
|
||||||
|
|
||||||
def get_dict():
|
|
||||||
"""Return all definitions as a dict indexed by coin keys."""
|
|
||||||
return {coin["key"]: coin for coin in get_list()}
|
|
@ -5,15 +5,15 @@ import time
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
import coin_defs
|
import coin_info
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
OPTIONAL_KEYS = ("links", "notes", "wallet")
|
OPTIONAL_KEYS = ("links", "notes", "wallet")
|
||||||
ALLOWED_SUPPORT_STATUS = ("yes", "no", "planned", "soon")
|
ALLOWED_SUPPORT_STATUS = ("yes", "no", "planned", "soon")
|
||||||
|
|
||||||
OVERRIDES = coin_defs.load_json("coins_details.override.json")
|
OVERRIDES = coin_info.load_json("coins_details.override.json")
|
||||||
VERSIONS = coin_defs.latest_releases()
|
VERSIONS = coin_info.latest_releases()
|
||||||
|
|
||||||
COINMAKETCAP_CACHE = os.path.join(os.path.dirname(__file__), "coinmarketcap.json")
|
COINMAKETCAP_CACHE = os.path.join(os.path.dirname(__file__), "coinmarketcap.json")
|
||||||
|
|
||||||
@ -292,16 +292,15 @@ def apply_overrides(coins):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
defs = coin_defs.get_all()
|
defs = coin_info.get_all()
|
||||||
all_coins = sum(defs.values(), [])
|
support_info = coin_info.support_info(defs, erc20_versions=VERSIONS)
|
||||||
support_info = coin_defs.support_info(all_coins, erc20_versions=VERSIONS)
|
|
||||||
|
|
||||||
coins = {}
|
coins = {}
|
||||||
coins.update(update_coins(defs["coins"], support_info))
|
coins.update(update_coins(defs.coins, support_info))
|
||||||
coins.update(update_erc20(defs["erc20"], support_info))
|
coins.update(update_erc20(defs.erc20, support_info))
|
||||||
coins.update(update_ethereum_networks(defs["eth"], support_info))
|
coins.update(update_ethereum_networks(defs.eth, support_info))
|
||||||
coins.update(update_simple(defs["nem"], support_info, "mosaic"))
|
coins.update(update_simple(defs.nem, support_info, "mosaic"))
|
||||||
coins.update(update_simple(defs["misc"], support_info, "coin"))
|
coins.update(update_simple(defs.misc, support_info, "coin"))
|
||||||
|
|
||||||
apply_overrides(coins)
|
apply_overrides(coins)
|
||||||
update_marketcaps(coins)
|
update_marketcaps(coins)
|
||||||
@ -311,5 +310,5 @@ if __name__ == "__main__":
|
|||||||
details = dict(coins=coins, info=info)
|
details = dict(coins=coins, info=info)
|
||||||
|
|
||||||
print(json.dumps(info, sort_keys=True, indent=4))
|
print(json.dumps(info, sort_keys=True, indent=4))
|
||||||
with open(os.path.join(coin_defs.DEFS_DIR, "coins_details.json"), "w") as f:
|
with open(os.path.join(coin_info.DEFS_DIR, "coins_details.json"), "w") as f:
|
||||||
json.dump(details, f, sort_keys=True, indent=4)
|
json.dump(details, f, sort_keys=True, indent=4)
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import click
|
import click
|
||||||
import coin_defs
|
import coin_info
|
||||||
import json
|
import json
|
||||||
|
|
||||||
SUPPORT_INFO = coin_defs.get_support_data()
|
SUPPORT_INFO = coin_info.get_support_data()
|
||||||
|
|
||||||
MANDATORY_ENTRIES = ("trezor1", "trezor2", "connect", "webwallet")
|
MANDATORY_ENTRIES = ("trezor1", "trezor2", "connect", "webwallet")
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ def update_support(key, entry, value):
|
|||||||
|
|
||||||
|
|
||||||
def write_support_info():
|
def write_support_info():
|
||||||
with open(os.path.join(coin_defs.DEFS_DIR, "support.json"), "w") as f:
|
with open(os.path.join(coin_info.DEFS_DIR, "support.json"), "w") as f:
|
||||||
json.dump(SUPPORT_INFO, f, indent=4)
|
json.dump(SUPPORT_INFO, f, indent=4)
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
|
|
||||||
@ -69,11 +69,11 @@ def check():
|
|||||||
here for convenience and because it makes sense. But it's preferable to run it
|
here for convenience and because it makes sense. But it's preferable to run it
|
||||||
as part of 'coin_gen.py check'.
|
as part of 'coin_gen.py check'.
|
||||||
"""
|
"""
|
||||||
defs = coin_defs.get_all()
|
defs = coin_info.get_all()
|
||||||
support_data = coin_defs.get_support_data()
|
support_data = coin_info.get_support_data()
|
||||||
import coin_gen
|
import coin_gen
|
||||||
|
|
||||||
if not coin_gen.check_support(defs, support_data):
|
if not coin_gen.check_support(defs, support_data, fail_missing=True):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ def show(keyword):
|
|||||||
Only coins listed in support.json are considered "supported". That means that
|
Only coins listed in support.json are considered "supported". That means that
|
||||||
Ethereum networks, ERC20 tokens and NEM mosaics will probably show up wrong.
|
Ethereum networks, ERC20 tokens and NEM mosaics will probably show up wrong.
|
||||||
"""
|
"""
|
||||||
defs = coin_defs.get_list()
|
defs = coin_info.get_all().as_list()
|
||||||
|
|
||||||
if keyword:
|
if keyword:
|
||||||
for coin in defs:
|
for coin in defs:
|
||||||
@ -138,7 +138,7 @@ def set(support_key, entries, dry_run):
|
|||||||
Entries with other names will be inserted into "others". This is a good place
|
Entries with other names will be inserted into "others". This is a good place
|
||||||
to store links to 3rd party software, such as Electrum forks or claim tools.
|
to store links to 3rd party software, such as Electrum forks or claim tools.
|
||||||
"""
|
"""
|
||||||
coins = coin_defs.get_dict()
|
coins = coin_info.get_all().as_dict()
|
||||||
if support_key not in coins:
|
if support_key not in coins:
|
||||||
click.echo("Failed to find key {}".format(support_key))
|
click.echo("Failed to find key {}".format(support_key))
|
||||||
click.echo("Use 'support.py show' to search for the right one.")
|
click.echo("Use 'support.py show' to search for the right one.")
|
||||||
|
Loading…
Reference in New Issue
Block a user