crypttrace 0.17.0__tar.gz → 0.18.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {crypttrace-0.17.0/src/crypttrace.egg-info → crypttrace-0.18.0}/PKG-INFO +9 -1
- {crypttrace-0.17.0 → crypttrace-0.18.0}/README.md +8 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/__init__.py +1 -1
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/labels.py +7 -3
- crypttrace-0.18.0/src/crypttrace/labels/names.py +8 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/tonapi.py +2 -7
- crypttrace-0.18.0/src/crypttrace/labels/tronscan.py +105 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0/src/crypttrace.egg-info}/PKG-INFO +9 -1
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace.egg-info/SOURCES.txt +2 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/LICENSE +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/pyproject.toml +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/setup.cfg +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/addresses.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/analysis.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/assess.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/assets.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/bridges.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/chains.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/cli.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/config.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/drain.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/evidence.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/__init__.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/bitcoin.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/etherscan.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/http.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/solana.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/ton.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/fetchers/tron.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/freeze.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/funder.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/investigate.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/__init__.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/audit.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/bulk.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/known.json +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/labels/partial.json +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/offramp.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/poisoning.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/prices.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/render.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/report.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/spam.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/store.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/trace.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/verify.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/watch.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/web/index.html +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace/webapp.py +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace.egg-info/dependency_links.txt +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace.egg-info/entry_points.txt +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace.egg-info/requires.txt +0 -0
- {crypttrace-0.17.0 → crypttrace-0.18.0}/src/crypttrace.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crypttrace
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: OSINT toolkit for crypto investigations: trace stolen funds across Ethereum, Bitcoin, Tron, Solana and TON
|
|
5
5
|
Author: bobslayerX
|
|
6
6
|
License-Expression: MIT
|
|
@@ -104,6 +104,7 @@ export TRONGRID_API_KEY=xxxx # optional: higher TronGrid quota
|
|
|
104
104
|
export CRYPTTRACE_SOLANA_RPC=https://… # optional: your own (faster) Solana RPC
|
|
105
105
|
export TONCENTER_API_KEY=xxxx # optional: toncenter allows ~1 request/s without it
|
|
106
106
|
export TONAPI_KEY=xxxx # optional: faster tonapi name lookups on TON
|
|
107
|
+
export TRONSCAN_API_KEY=xxxx # optional: Tron exchange and scam tags from Tronscan
|
|
107
108
|
```
|
|
108
109
|
|
|
109
110
|
(In PowerShell: `$env:TRONGRID_API_KEY = "xxxx"` and so on.)
|
|
@@ -537,6 +538,13 @@ accounts. These become labels of kind `explorer-tag`, cached for a week. A
|
|
|
537
538
|
"kucoin-1.ton" — is not taken as a label. A trace stops at a DEX: the funds
|
|
538
539
|
come back to the sender in another token.
|
|
539
540
|
|
|
541
|
+
**Tron: tags from Tronscan.** With a free Tronscan API key (`TRONSCAN_API_KEY`,
|
|
542
|
+
created in a Tronscan account), Tron addresses the curated set does not know
|
|
543
|
+
get Tronscan's tags: exchange wallets ("Binance-Cold 1", "Okex 1") become
|
|
544
|
+
exchange labels and a red tag (scam, phishing) makes the address a scam — both
|
|
545
|
+
as `explorer-tag` labels naming Tronscan as the source, cached for a week.
|
|
546
|
+
Without a key nothing is fetched.
|
|
547
|
+
|
|
540
548
|
**Exchange deposits with a memo.** A TON exchange takes all customers' deposits
|
|
541
549
|
into one hot wallet and tells them apart by the transfer comment, the *memo*.
|
|
542
550
|
The memo is the lead: it names one account at the exchange, which holds that
|
|
@@ -70,6 +70,7 @@ export TRONGRID_API_KEY=xxxx # optional: higher TronGrid quota
|
|
|
70
70
|
export CRYPTTRACE_SOLANA_RPC=https://… # optional: your own (faster) Solana RPC
|
|
71
71
|
export TONCENTER_API_KEY=xxxx # optional: toncenter allows ~1 request/s without it
|
|
72
72
|
export TONAPI_KEY=xxxx # optional: faster tonapi name lookups on TON
|
|
73
|
+
export TRONSCAN_API_KEY=xxxx # optional: Tron exchange and scam tags from Tronscan
|
|
73
74
|
```
|
|
74
75
|
|
|
75
76
|
(In PowerShell: `$env:TRONGRID_API_KEY = "xxxx"` and so on.)
|
|
@@ -503,6 +504,13 @@ accounts. These become labels of kind `explorer-tag`, cached for a week. A
|
|
|
503
504
|
"kucoin-1.ton" — is not taken as a label. A trace stops at a DEX: the funds
|
|
504
505
|
come back to the sender in another token.
|
|
505
506
|
|
|
507
|
+
**Tron: tags from Tronscan.** With a free Tronscan API key (`TRONSCAN_API_KEY`,
|
|
508
|
+
created in a Tronscan account), Tron addresses the curated set does not know
|
|
509
|
+
get Tronscan's tags: exchange wallets ("Binance-Cold 1", "Okex 1") become
|
|
510
|
+
exchange labels and a red tag (scam, phishing) makes the address a scam — both
|
|
511
|
+
as `explorer-tag` labels naming Tronscan as the source, cached for a week.
|
|
512
|
+
Without a key nothing is fetched.
|
|
513
|
+
|
|
506
514
|
**Exchange deposits with a memo.** A TON exchange takes all customers' deposits
|
|
507
515
|
into one hot wallet and tells them apart by the transfer comment, the *memo*.
|
|
508
516
|
The memo is the lead: it names one account at the exchange, which holds that
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""crypttrace — OSINT crypto investigation CLI."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.18.0"
|
|
@@ -17,7 +17,7 @@ from typing import Optional, Dict, List
|
|
|
17
17
|
import requests
|
|
18
18
|
|
|
19
19
|
from crypttrace import addresses, config
|
|
20
|
-
from crypttrace.labels import bulk, tonapi
|
|
20
|
+
from crypttrace.labels import bulk, tonapi, tronscan
|
|
21
21
|
|
|
22
22
|
_HERE = Path(__file__).parent
|
|
23
23
|
_IMPORTED = config.DATA_DIR / "imported_labels.json"
|
|
@@ -189,15 +189,19 @@ def lookup(address: str) -> Optional[dict]:
|
|
|
189
189
|
found = _match_partial(address) or bulk.lookup(address)
|
|
190
190
|
if not found and (len(address) == 48 or ":" in address):
|
|
191
191
|
found = tonapi.lookup(address) # cached explorer tag, no network here
|
|
192
|
+
elif not found and len(address) == 34 and address.startswith("T"):
|
|
193
|
+
found = tronscan.lookup(address)
|
|
192
194
|
return found
|
|
193
195
|
|
|
194
196
|
|
|
195
197
|
def enrich(addrs, chain: str) -> None:
|
|
196
|
-
"""Fetch explorer tags the curated set lacks (TON: tonapi
|
|
198
|
+
"""Fetch explorer tags the curated set lacks (TON: tonapi, Tron: Tronscan). Network, cached."""
|
|
199
|
+
_load()
|
|
197
200
|
if chain == "ton":
|
|
198
|
-
_load()
|
|
199
201
|
tonapi.enrich(a for a in addrs
|
|
200
202
|
if a and not _KNOWN.get((addresses.ton_friendly(a) or a).lower()))
|
|
203
|
+
elif chain == "tron":
|
|
204
|
+
tronscan.enrich(a for a in addrs if a and not _KNOWN.get(a.lower()))
|
|
201
205
|
|
|
202
206
|
|
|
203
207
|
def is_deposit(address: str) -> bool:
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Exchange names as explorers spell them — shared by the explorer-tag sources."""
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
# custodial platforms that hold KYC and can freeze: a deposit there is a lead
|
|
5
|
+
EXCHANGES = re.compile(
|
|
6
|
+
r"\b(binance|bybit|okx|okex|kucoin|htx|huobi|gate(\.io)?|mexc|bitget|kraken|coinbase|"
|
|
7
|
+
r"bitfinex|bingx|bitmart|lbank|whitebit|exmo|coinex|poloniex|crypto\.com|bitpanda|"
|
|
8
|
+
r"bithumb|upbit|cryptobot|crypto bot|xrocket|wallet in telegram|telegram wallet)\b", re.I)
|
|
@@ -26,6 +26,7 @@ import requests
|
|
|
26
26
|
|
|
27
27
|
from crypttrace import addresses, config
|
|
28
28
|
from crypttrace.fetchers import http
|
|
29
|
+
from crypttrace.labels.names import EXCHANGES
|
|
29
30
|
|
|
30
31
|
API = "https://tonapi.io/v2/accounts/{}"
|
|
31
32
|
CACHE = config.DATA_DIR / "tonapi_names.json"
|
|
@@ -33,12 +34,6 @@ MAX_AGE = 7 * 24 * 3600
|
|
|
33
34
|
_KEY = os.environ.get("TONAPI_KEY")
|
|
34
35
|
http.MIN_INTERVAL["tonapi.io"] = 0.12 if _KEY else 1.1
|
|
35
36
|
|
|
36
|
-
# custodial platforms that hold KYC and can freeze: a deposit there is a lead
|
|
37
|
-
_EXCHANGES = re.compile(
|
|
38
|
-
r"\b(binance|bybit|okx|okex|kucoin|htx|huobi|gate(\.io)?|mexc|bitget|kraken|coinbase|"
|
|
39
|
-
r"bitfinex|bingx|bitmart|lbank|whitebit|exmo|coinex|poloniex|crypto\.com|bitpanda|"
|
|
40
|
-
r"bithumb|upbit|cryptobot|crypto bot|xrocket|wallet in telegram|telegram wallet)\b", re.I)
|
|
41
|
-
|
|
42
37
|
_cache: Optional[Dict[str, dict]] = None
|
|
43
38
|
|
|
44
39
|
|
|
@@ -73,7 +68,7 @@ def classify(account: dict) -> Optional[dict]:
|
|
|
73
68
|
return {"name": name or "DEX contract", "type": "dex"}
|
|
74
69
|
if not name or self_named:
|
|
75
70
|
return None
|
|
76
|
-
if
|
|
71
|
+
if EXCHANGES.search(name):
|
|
77
72
|
memo = " (memo required)" if account.get("memo_required") else ""
|
|
78
73
|
return {"name": f"{name}{memo}", "type": "exchange", "memo_required": bool(account.get("memo_required"))}
|
|
79
74
|
return {"name": name, "type": "service"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Tron address tags from Tronscan — exchange wallets and risk warnings.
|
|
2
|
+
|
|
3
|
+
Tronscan tags exchange hot and cold wallets ("Binance-Cold 1", "OKX-Hot") and
|
|
4
|
+
puts red tags on addresses it flags as scams or phishing. Both become labels
|
|
5
|
+
of kind "explorer-tag", with Tronscan named as the source; a red tag makes the
|
|
6
|
+
address a scam. Grey tags and user feedback are not enough to call an address
|
|
7
|
+
anything.
|
|
8
|
+
|
|
9
|
+
Needs a free API key (TRONSCAN_API_KEY, created in a Tronscan account); without
|
|
10
|
+
one nothing is fetched and Tron labels come from the curated set alone.
|
|
11
|
+
Lookups are cached on disk for a week; only `enrich()` uses the network.
|
|
12
|
+
"""
|
|
13
|
+
import datetime as dt
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
import time
|
|
18
|
+
from typing import Dict, Iterable, Optional
|
|
19
|
+
|
|
20
|
+
import requests
|
|
21
|
+
|
|
22
|
+
from crypttrace import config
|
|
23
|
+
from crypttrace.fetchers import http
|
|
24
|
+
from crypttrace.labels.names import EXCHANGES
|
|
25
|
+
|
|
26
|
+
API = "https://apilist.tronscanapi.com/api/accountv2"
|
|
27
|
+
CACHE = config.DATA_DIR / "tronscan_tags.json"
|
|
28
|
+
MAX_AGE = 7 * 24 * 3600
|
|
29
|
+
http.MIN_INTERVAL["apilist.tronscanapi.com"] = 0.25
|
|
30
|
+
_cache: Optional[Dict[str, dict]] = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _key() -> Optional[str]:
|
|
34
|
+
k = os.environ.get("TRONSCAN_API_KEY")
|
|
35
|
+
if not k and sys.platform == "win32": # set with [Environment]::SetEnvironmentVariable(..., "User")
|
|
36
|
+
try:
|
|
37
|
+
import winreg
|
|
38
|
+
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment") as reg:
|
|
39
|
+
k = winreg.QueryValueEx(reg, "TRONSCAN_API_KEY")[0]
|
|
40
|
+
except OSError:
|
|
41
|
+
k = None
|
|
42
|
+
return (k or "").strip() or None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _load() -> Dict[str, dict]:
|
|
46
|
+
global _cache
|
|
47
|
+
if _cache is None:
|
|
48
|
+
try:
|
|
49
|
+
_cache = json.loads(CACHE.read_text(encoding="utf-8"))
|
|
50
|
+
except (OSError, ValueError):
|
|
51
|
+
_cache = {}
|
|
52
|
+
return _cache
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _save() -> None:
|
|
56
|
+
try:
|
|
57
|
+
CACHE.parent.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
tmp = CACHE.with_suffix(".tmp")
|
|
59
|
+
tmp.write_text(json.dumps(_load(), ensure_ascii=False), encoding="utf-8")
|
|
60
|
+
tmp.replace(CACHE)
|
|
61
|
+
except OSError:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def classify(account: dict) -> Optional[dict]:
|
|
66
|
+
"""A label from one Tronscan account record, or None if it names nothing."""
|
|
67
|
+
red = (account.get("redTag") or "").strip()
|
|
68
|
+
tag = (account.get("publicTag") or account.get("addressTag") or "").strip()
|
|
69
|
+
if red:
|
|
70
|
+
return {"name": f"{tag or red} (Tronscan: {red})", "type": "scam"}
|
|
71
|
+
if not tag:
|
|
72
|
+
return None
|
|
73
|
+
if EXCHANGES.search(tag.replace("-", " ")):
|
|
74
|
+
return {"name": tag, "type": "exchange"}
|
|
75
|
+
return {"name": tag, "type": "service"}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def lookup(address: str) -> Optional[dict]:
|
|
79
|
+
"""Cached Tronscan label, without touching the network."""
|
|
80
|
+
entry = _load().get(address)
|
|
81
|
+
if not entry or not entry.get("label"):
|
|
82
|
+
return None
|
|
83
|
+
return {**entry["label"], "chain": "tron", "source_kind": "explorer-tag",
|
|
84
|
+
"source": f"Tronscan address tag, fetched {entry.get('day', '')}"}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def enrich(addrs: Iterable[str]) -> None:
|
|
88
|
+
"""Fetch Tronscan tags for addresses not in the cache (or stale). No key, no fetch."""
|
|
89
|
+
key = _key()
|
|
90
|
+
if not key:
|
|
91
|
+
return
|
|
92
|
+
cache, now, changed = _load(), time.time(), False
|
|
93
|
+
for a in dict.fromkeys(addrs):
|
|
94
|
+
if not a or not a.startswith("T") or len(a) != 34 or now - cache.get(a, {}).get("at", 0) < MAX_AGE:
|
|
95
|
+
continue
|
|
96
|
+
try:
|
|
97
|
+
rec = http.request_json(API, {"address": a}, timeout=20, headers={"TRON-PRO-API-KEY": key})
|
|
98
|
+
except (http.RateLimited, requests.RequestException, ValueError):
|
|
99
|
+
continue
|
|
100
|
+
if not isinstance(rec, dict) or "__status__" in rec:
|
|
101
|
+
continue
|
|
102
|
+
cache[a] = {"at": now, "day": dt.date.today().isoformat(), "label": classify(rec)}
|
|
103
|
+
changed = True
|
|
104
|
+
if changed:
|
|
105
|
+
_save()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crypttrace
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: OSINT toolkit for crypto investigations: trace stolen funds across Ethereum, Bitcoin, Tron, Solana and TON
|
|
5
5
|
Author: bobslayerX
|
|
6
6
|
License-Expression: MIT
|
|
@@ -104,6 +104,7 @@ export TRONGRID_API_KEY=xxxx # optional: higher TronGrid quota
|
|
|
104
104
|
export CRYPTTRACE_SOLANA_RPC=https://… # optional: your own (faster) Solana RPC
|
|
105
105
|
export TONCENTER_API_KEY=xxxx # optional: toncenter allows ~1 request/s without it
|
|
106
106
|
export TONAPI_KEY=xxxx # optional: faster tonapi name lookups on TON
|
|
107
|
+
export TRONSCAN_API_KEY=xxxx # optional: Tron exchange and scam tags from Tronscan
|
|
107
108
|
```
|
|
108
109
|
|
|
109
110
|
(In PowerShell: `$env:TRONGRID_API_KEY = "xxxx"` and so on.)
|
|
@@ -537,6 +538,13 @@ accounts. These become labels of kind `explorer-tag`, cached for a week. A
|
|
|
537
538
|
"kucoin-1.ton" — is not taken as a label. A trace stops at a DEX: the funds
|
|
538
539
|
come back to the sender in another token.
|
|
539
540
|
|
|
541
|
+
**Tron: tags from Tronscan.** With a free Tronscan API key (`TRONSCAN_API_KEY`,
|
|
542
|
+
created in a Tronscan account), Tron addresses the curated set does not know
|
|
543
|
+
get Tronscan's tags: exchange wallets ("Binance-Cold 1", "Okex 1") become
|
|
544
|
+
exchange labels and a red tag (scam, phishing) makes the address a scam — both
|
|
545
|
+
as `explorer-tag` labels naming Tronscan as the source, cached for a week.
|
|
546
|
+
Without a key nothing is fetched.
|
|
547
|
+
|
|
540
548
|
**Exchange deposits with a memo.** A TON exchange takes all customers' deposits
|
|
541
549
|
into one hot wallet and tells them apart by the transfer comment, the *memo*.
|
|
542
550
|
The memo is the lead: it names one account at the exchange, which holds that
|
|
@@ -44,6 +44,8 @@ src/crypttrace/labels/audit.py
|
|
|
44
44
|
src/crypttrace/labels/bulk.py
|
|
45
45
|
src/crypttrace/labels/known.json
|
|
46
46
|
src/crypttrace/labels/labels.py
|
|
47
|
+
src/crypttrace/labels/names.py
|
|
47
48
|
src/crypttrace/labels/partial.json
|
|
48
49
|
src/crypttrace/labels/tonapi.py
|
|
50
|
+
src/crypttrace/labels/tronscan.py
|
|
49
51
|
src/crypttrace/web/index.html
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|