cryptoshield 0.2.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 yossweh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,157 @@
1
+ Metadata-Version: 2.4
2
+ Name: cryptoshield
3
+ Version: 0.2.0
4
+ Summary: All-in-one crypto security toolkit — honeypot, approvals, rugpull, phishing
5
+ Author-email: yossweh <cilokcilok15@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yossweh/cryptoshield
8
+ Project-URL: Repository, https://github.com/yossweh/cryptoshield
9
+ Project-URL: Issues, https://github.com/yossweh/cryptoshield/issues
10
+ Keywords: crypto,security,honeypot,rugpull,web3,defi,approval
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: typer>=0.9.0
21
+ Requires-Dist: web3>=6.0.0
22
+ Requires-Dist: requests>=2.28.0
23
+ Dynamic: license-file
24
+
25
+ # šŸ›” CryptoShield
26
+
27
+ **All-in-one crypto security toolkit.** Check tokens before you buy. Scan your wallet for dangerous approvals. Detect rugpulls. Block phishing sites.
28
+
29
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://python.org)
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
31
+ [![PyPI](https://img.shields.io/pypi/v/cryptoshield.svg)](https://pypi.org/project/cryptoshield/)
32
+
33
+ ## Features
34
+
35
+ - **šŸÆ Honeypot Detection** — Can you sell? Hidden taxes? Mint function? Check before you buy.
36
+ - **šŸ“‹ Approval Scanner** — Find all token approvals on your wallet. Flag dangerous unlimited approvals.
37
+ - **šŸ”“ Rugpull Scorer** — Analyze contracts for common rug patterns. Score 0-100.
38
+ - **šŸŽ£ Phishing Checker** — 60+ known scam domains. Typosquatting, fake airdrops, wallet drainers.
39
+ - **ā˜€ļø Solana Support** — Check SPL tokens, freeze/mint authority, Jupiter listing status.
40
+ - **šŸ“¦ Batch Mode** — Check 100+ tokens/wallets from a file.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ pip install cryptoshield
46
+ ```
47
+
48
+ Or from source:
49
+
50
+ ```bash
51
+ git clone https://github.com/yossweh/cryptoshield
52
+ cd cryptoshield
53
+ pip install -e .
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ### Full security report (EVM)
59
+ ```bash
60
+ cryptoshield check 0xdAC17F958D2ee523a2206206994597C13D831ec7
61
+ cryptoshield check 0xToken --chain bsc
62
+ cryptoshield check 0xToken --quick # honeypot only
63
+ ```
64
+
65
+ ### Solana token check
66
+ ```bash
67
+ cryptoshield check EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --chain solana
68
+ ```
69
+
70
+ ### Scan wallet approvals
71
+ ```bash
72
+ cryptoshield approvals 0xYourWallet
73
+ cryptoshield approvals 0xYourWallet --chain polygon
74
+ ```
75
+
76
+ ### Check phishing URL
77
+ ```bash
78
+ cryptoshield check-url uniswap-airdrop.com
79
+ cryptoshield check-url https://app.uniswap.org
80
+ cryptoshield check-url metamask-sync.xyz
81
+ ```
82
+
83
+ ### Solana wallet scan
84
+ ```bash
85
+ cryptoshield solana YourSolanaWalletAddress
86
+ ```
87
+
88
+ ### Batch check
89
+ ```bash
90
+ cryptoshield batch tokens.txt --mode honeypot
91
+ cryptoshield batch tokens.txt --mode honeypot --chain solana
92
+ cryptoshield batch wallets.txt --mode approvals --chain bsc
93
+ ```
94
+
95
+ ## Example Output
96
+
97
+ ```
98
+ šŸ›” CRYPTO SHIELD REPORT
99
+ ━━━━━━━━━━━━━━━━━━━━━━━
100
+
101
+ šŸÆ HONEYPOT CHECK — Tether USD (USDT)
102
+ āœ… Can sell: YES
103
+ āœ… Tax: 0% buy / 0% sell
104
+ āŒ Owner can mint: YES — infinite supply risk
105
+ āŒ Owner can change balances: YES
106
+ āœ… Contract: Verified
107
+ ā„¹ļø Holders: 14,585,422
108
+ āš ļø Risk Score: 30/100 — MEDIUM RISK
109
+
110
+ šŸŽ£ PHISHING CHECK — uniswap-airdrop.com
111
+ 🚨 KNOWN SCAM DOMAIN — DO NOT VISIT
112
+ āŒ KNOWN SCAM DOMAIN — uniswap-airdrop.com is in scam database
113
+
114
+ ā˜€ļø SOLANA TOKEN CHECK — SafeToken (SAFE)
115
+ āœ… Listed on Jupiter
116
+ āœ… On Jupiter Strict List (vetted)
117
+ āœ… Freeze Authority: None
118
+ āœ… Mint Authority: None (fixed supply)
119
+ āœ… Holders: 5,432
120
+ āœ… Risk Score: 0/100 — LOW RISK
121
+ ```
122
+
123
+ ## Supported Chains
124
+
125
+ | Chain | Honeypot | Approvals | Rugpull |
126
+ |-------|----------|-----------|---------|
127
+ | Ethereum | āœ… | āœ… | āœ… |
128
+ | BSC | āœ… | āœ… | āœ… |
129
+ | Polygon | āœ… | āœ… | āœ… |
130
+ | Arbitrum | āœ… | āœ… | āœ… |
131
+ | Optimism | āœ… | āœ… | āœ… |
132
+ | Base | āœ… | āœ… | āœ… |
133
+ | Avalanche | āœ… | āœ… | āœ… |
134
+ | Fantom | āœ… | āœ… | āœ… |
135
+ | Solana | āœ… | — | āœ… |
136
+
137
+ ## Data Sources
138
+
139
+ - **GoPlus Security API** — Honeypot detection, token security analysis (free, no key)
140
+ - **Jupiter API** — Solana token data, strict list
141
+ - **Birdeye API** — Solana holder count, volume
142
+ - **On-chain data** — Approval events, contract code, ownership (direct RPC)
143
+ - **Heuristics** — URL pattern matching, domain analysis, typosquatting detection
144
+ - **Community scam database** — 60+ known phishing domains
145
+
146
+ ## Contributing
147
+
148
+ PRs welcome! Especially:
149
+
150
+ - More scam domains / phishing patterns
151
+ - More chain support (TON, Sui, Aptos)
152
+ - Better rugpull heuristics
153
+ - UI improvements
154
+
155
+ ## License
156
+
157
+ MIT
@@ -0,0 +1,133 @@
1
+ # šŸ›” CryptoShield
2
+
3
+ **All-in-one crypto security toolkit.** Check tokens before you buy. Scan your wallet for dangerous approvals. Detect rugpulls. Block phishing sites.
4
+
5
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://python.org)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
7
+ [![PyPI](https://img.shields.io/pypi/v/cryptoshield.svg)](https://pypi.org/project/cryptoshield/)
8
+
9
+ ## Features
10
+
11
+ - **šŸÆ Honeypot Detection** — Can you sell? Hidden taxes? Mint function? Check before you buy.
12
+ - **šŸ“‹ Approval Scanner** — Find all token approvals on your wallet. Flag dangerous unlimited approvals.
13
+ - **šŸ”“ Rugpull Scorer** — Analyze contracts for common rug patterns. Score 0-100.
14
+ - **šŸŽ£ Phishing Checker** — 60+ known scam domains. Typosquatting, fake airdrops, wallet drainers.
15
+ - **ā˜€ļø Solana Support** — Check SPL tokens, freeze/mint authority, Jupiter listing status.
16
+ - **šŸ“¦ Batch Mode** — Check 100+ tokens/wallets from a file.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install cryptoshield
22
+ ```
23
+
24
+ Or from source:
25
+
26
+ ```bash
27
+ git clone https://github.com/yossweh/cryptoshield
28
+ cd cryptoshield
29
+ pip install -e .
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Full security report (EVM)
35
+ ```bash
36
+ cryptoshield check 0xdAC17F958D2ee523a2206206994597C13D831ec7
37
+ cryptoshield check 0xToken --chain bsc
38
+ cryptoshield check 0xToken --quick # honeypot only
39
+ ```
40
+
41
+ ### Solana token check
42
+ ```bash
43
+ cryptoshield check EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --chain solana
44
+ ```
45
+
46
+ ### Scan wallet approvals
47
+ ```bash
48
+ cryptoshield approvals 0xYourWallet
49
+ cryptoshield approvals 0xYourWallet --chain polygon
50
+ ```
51
+
52
+ ### Check phishing URL
53
+ ```bash
54
+ cryptoshield check-url uniswap-airdrop.com
55
+ cryptoshield check-url https://app.uniswap.org
56
+ cryptoshield check-url metamask-sync.xyz
57
+ ```
58
+
59
+ ### Solana wallet scan
60
+ ```bash
61
+ cryptoshield solana YourSolanaWalletAddress
62
+ ```
63
+
64
+ ### Batch check
65
+ ```bash
66
+ cryptoshield batch tokens.txt --mode honeypot
67
+ cryptoshield batch tokens.txt --mode honeypot --chain solana
68
+ cryptoshield batch wallets.txt --mode approvals --chain bsc
69
+ ```
70
+
71
+ ## Example Output
72
+
73
+ ```
74
+ šŸ›” CRYPTO SHIELD REPORT
75
+ ━━━━━━━━━━━━━━━━━━━━━━━
76
+
77
+ šŸÆ HONEYPOT CHECK — Tether USD (USDT)
78
+ āœ… Can sell: YES
79
+ āœ… Tax: 0% buy / 0% sell
80
+ āŒ Owner can mint: YES — infinite supply risk
81
+ āŒ Owner can change balances: YES
82
+ āœ… Contract: Verified
83
+ ā„¹ļø Holders: 14,585,422
84
+ āš ļø Risk Score: 30/100 — MEDIUM RISK
85
+
86
+ šŸŽ£ PHISHING CHECK — uniswap-airdrop.com
87
+ 🚨 KNOWN SCAM DOMAIN — DO NOT VISIT
88
+ āŒ KNOWN SCAM DOMAIN — uniswap-airdrop.com is in scam database
89
+
90
+ ā˜€ļø SOLANA TOKEN CHECK — SafeToken (SAFE)
91
+ āœ… Listed on Jupiter
92
+ āœ… On Jupiter Strict List (vetted)
93
+ āœ… Freeze Authority: None
94
+ āœ… Mint Authority: None (fixed supply)
95
+ āœ… Holders: 5,432
96
+ āœ… Risk Score: 0/100 — LOW RISK
97
+ ```
98
+
99
+ ## Supported Chains
100
+
101
+ | Chain | Honeypot | Approvals | Rugpull |
102
+ |-------|----------|-----------|---------|
103
+ | Ethereum | āœ… | āœ… | āœ… |
104
+ | BSC | āœ… | āœ… | āœ… |
105
+ | Polygon | āœ… | āœ… | āœ… |
106
+ | Arbitrum | āœ… | āœ… | āœ… |
107
+ | Optimism | āœ… | āœ… | āœ… |
108
+ | Base | āœ… | āœ… | āœ… |
109
+ | Avalanche | āœ… | āœ… | āœ… |
110
+ | Fantom | āœ… | āœ… | āœ… |
111
+ | Solana | āœ… | — | āœ… |
112
+
113
+ ## Data Sources
114
+
115
+ - **GoPlus Security API** — Honeypot detection, token security analysis (free, no key)
116
+ - **Jupiter API** — Solana token data, strict list
117
+ - **Birdeye API** — Solana holder count, volume
118
+ - **On-chain data** — Approval events, contract code, ownership (direct RPC)
119
+ - **Heuristics** — URL pattern matching, domain analysis, typosquatting detection
120
+ - **Community scam database** — 60+ known phishing domains
121
+
122
+ ## Contributing
123
+
124
+ PRs welcome! Especially:
125
+
126
+ - More scam domains / phishing patterns
127
+ - More chain support (TON, Sui, Aptos)
128
+ - Better rugpull heuristics
129
+ - UI improvements
130
+
131
+ ## License
132
+
133
+ MIT
@@ -0,0 +1,4 @@
1
+ """CryptoShield — All-in-one crypto security toolkit."""
2
+
3
+ __version__ = "0.2.0"
4
+ __author__ = "yossweh"
@@ -0,0 +1,185 @@
1
+ """Token approval scanner — find dangerous approvals on your wallet.
2
+
3
+ Scans on-chain Approval events to find all active token approvals.
4
+ """
5
+
6
+ from web3 import Web3
7
+ from .utils import (
8
+ get_web3, checksum, label_address, ERC20_ABI, APPROVAL_EVENT,
9
+ KNOWN_ADDRESSES, print_header, print_ok, print_warn, print_fail, print_info,
10
+ )
11
+
12
+ # Common approval spender labels
13
+ SPENDER_LABELS = {
14
+ **KNOWN_ADDRESSES,
15
+ "0x0000000000000000000000000000000000000000": "Zero Address (burn)",
16
+ "0x000000000000000000000000000000000000dead": "Dead Address (burn)",
17
+ }
18
+
19
+ # Approvals above this are considered "unlimited"
20
+ UNLIMITED_THRESHOLD = 2**250
21
+
22
+
23
+ def scan_approvals(wallet: str, chain: str = "eth", blocks_back: int = 100_000) -> list:
24
+ """Scan all token approvals for a wallet."""
25
+ w3 = get_web3(chain)
26
+ wallet = checksum(wallet)
27
+
28
+ current_block = w3.eth.block_number
29
+ from_block = max(0, current_block - blocks_back)
30
+
31
+ # Get Approval events where owner = wallet
32
+ approval_topic = w3.keccak(
33
+ text="Approval(address,address,uint256)"
34
+ ).hex()
35
+
36
+ try:
37
+ logs = w3.eth.get_logs({
38
+ "fromBlock": from_block,
39
+ "toBlock": current_block,
40
+ "topics": [
41
+ approval_topic,
42
+ "0x" + wallet[2:].lower().zfill(64), # owner
43
+ ],
44
+ })
45
+ except Exception as e:
46
+ return [{"error": str(e)}]
47
+
48
+ # Deduplicate: keep latest approval per (token, spender)
49
+ approvals = {}
50
+ for log in logs:
51
+ try:
52
+ token_addr = log["address"]
53
+ spender = "0x" + log["topics"][2].hex()[-40:]
54
+ spender = Web3.to_checksum_address(spender)
55
+ value = int(log["data"].hex(), 16)
56
+
57
+ key = (token_addr.lower(), spender.lower())
58
+ approvals[key] = {
59
+ "token": token_addr,
60
+ "spender": spender,
61
+ "value": value,
62
+ "block": log["blockNumber"],
63
+ }
64
+ except Exception:
65
+ continue
66
+
67
+ # Filter: only keep current approvals (check on-chain allowance)
68
+ active = []
69
+ for (token_lower, spender_lower), info in approvals.items():
70
+ if info["value"] == 0:
71
+ continue
72
+
73
+ try:
74
+ contract = w3.eth.contract(
75
+ address=checksum(info["token"]), abi=ERC20_ABI
76
+ )
77
+ current_allowance = contract.functions.allowance(
78
+ wallet, checksum(info["spender"])
79
+ ).call()
80
+
81
+ if current_allowance == 0:
82
+ continue
83
+
84
+ # Get token info
85
+ try:
86
+ name = contract.functions.name().call()
87
+ except Exception:
88
+ name = "Unknown"
89
+ try:
90
+ symbol = contract.functions.symbol().call()
91
+ except Exception:
92
+ symbol = "?"
93
+
94
+ is_unlimited = current_allowance >= UNLIMITED_THRESHOLD
95
+ spender_label = SPENDER_LABELS.get(
96
+ info["spender"].lower(), "Unknown Contract"
97
+ )
98
+
99
+ active.append({
100
+ "token": info["token"],
101
+ "token_name": name,
102
+ "token_symbol": symbol,
103
+ "spender": info["spender"],
104
+ "spender_label": spender_label,
105
+ "allowance": current_allowance,
106
+ "is_unlimited": is_unlimited,
107
+ "is_known": info["spender"].lower() in KNOWN_ADDRESSES,
108
+ })
109
+ except Exception:
110
+ continue
111
+
112
+ return active
113
+
114
+
115
+ def print_approval_report(approvals: list, wallet: str):
116
+ """Pretty-print approval scan results."""
117
+ if not approvals:
118
+ print_ok("No active approvals found — your wallet is clean!")
119
+ return
120
+
121
+ if "error" in approvals[0]:
122
+ print_fail(f"Error: {approvals[0]['error']}")
123
+ return
124
+
125
+ print_header(f"APPROVAL AUDIT — {wallet[:6]}...{wallet[-4:]}")
126
+
127
+ dangerous = []
128
+ caution = []
129
+ safe = []
130
+
131
+ for a in approvals:
132
+ if a["is_unlimited"] and not a["is_known"]:
133
+ dangerous.append(a)
134
+ elif a["is_unlimited"] and a["is_known"]:
135
+ caution.append(a)
136
+ else:
137
+ safe.append(a)
138
+
139
+ # Dangerous first
140
+ for a in dangerous:
141
+ print_fail(
142
+ f"{a['token_symbol']} → UNLIMITED to {label_address(a['spender'])}"
143
+ )
144
+ print(f" ⚔ RECOMMEND: revoke immediately")
145
+
146
+ # Caution
147
+ for a in caution:
148
+ print_warn(
149
+ f"{a['token_symbol']} → unlimited to {label_address(a['spender'])}"
150
+ )
151
+ print(f" Known protocol — consider reducing allowance")
152
+
153
+ # Safe
154
+ for a in safe:
155
+ if a["allowance"] > 10**18:
156
+ amount = f"{a['allowance'] / 10**18:.2f}"
157
+ else:
158
+ amount = str(a["allowance"])
159
+ print_ok(
160
+ f"{a['token_symbol']} → {amount} to {label_address(a['spender'])}"
161
+ )
162
+
163
+ print()
164
+ print_info(f"Total approvals: {len(approvals)}")
165
+ if dangerous:
166
+ print_fail(f"{len(dangerous)} HIGH RISK — revoke now!")
167
+ if caution:
168
+ print_warn(f"{len(caution)} caution — review recommended")
169
+
170
+
171
+ REVOKE4_ABI = [
172
+ {
173
+ "inputs": [
174
+ {"name": "token", "type": "address"},
175
+ {"name": "spender", "type": "address"},
176
+ ],
177
+ "name": "revoke",
178
+ "outputs": [],
179
+ "stateMutability": "nonpayable",
180
+ "type": "function",
181
+ }
182
+ ]
183
+
184
+ # revoke.xyz contract
185
+ REVOKE_CONTRACT = "0x000000000000Dd366e1DA4F6c8a2b2F9e01f6F1E"
@@ -0,0 +1,166 @@
1
+ """CryptoShield CLI — All-in-one crypto security toolkit."""
2
+
3
+ import sys
4
+ import typer
5
+
6
+ from . import __version__
7
+
8
+ app = typer.Typer(
9
+ name="cryptoshield",
10
+ help="šŸ›” CryptoShield — All-in-one crypto security toolkit",
11
+ add_completion=False,
12
+ )
13
+
14
+
15
+ @app.command()
16
+ def check(
17
+ address: str = typer.Argument(..., help="Token contract address"),
18
+ chain: str = typer.Option("eth", "-c", "--chain", help="Chain: eth, bsc, polygon, arbitrum, optimism, base, avalanche, fantom, solana"),
19
+ quick: bool = typer.Option(False, "-q", "--quick", help="Quick check (honeypot only)"),
20
+ ):
21
+ """Full security report for a token contract."""
22
+ if chain == "solana":
23
+ from .solana import check_solana_token, print_solana_token_report
24
+ print(f"\nšŸ›” CRYPTO SHIELD — Scanning Solana token {address[:10]}...")
25
+ print("━" * 50)
26
+ report = check_solana_token(address)
27
+ print_solana_token_report(report)
28
+ return
29
+
30
+ from .honeypot import check_honeypot, print_honeypot_report
31
+ from .rugpull import analyze_rugpull, print_rugpull_report
32
+
33
+ print(f"\nšŸ›” CRYPTO SHIELD — Scanning {address[:10]}... on {chain}")
34
+ print("━" * 50)
35
+
36
+ if quick:
37
+ report = check_honeypot(address, chain)
38
+ print_honeypot_report(report)
39
+ else:
40
+ report = analyze_rugpull(address, chain)
41
+ print_rugpull_report(report)
42
+ print()
43
+ hp = check_honeypot(address, chain)
44
+ print_honeypot_report(hp)
45
+
46
+
47
+ @app.command()
48
+ def approvals(
49
+ wallet: str = typer.Argument(..., help="Wallet address to scan"),
50
+ chain: str = typer.Option("eth", "-c", "--chain", help="Chain to scan"),
51
+ blocks: int = typer.Option(100000, "-b", "--blocks", help="How many blocks back to scan"),
52
+ ):
53
+ """Scan token approvals for a wallet."""
54
+ from .approvals import scan_approvals, print_approval_report
55
+
56
+ print(f"\nšŸ›” Scanning approvals for {wallet[:10]}... on {chain}")
57
+ results = scan_approvals(wallet, chain, blocks)
58
+ print_approval_report(results, wallet)
59
+
60
+
61
+ @app.command()
62
+ def rugpull(
63
+ address: str = typer.Argument(..., help="Token contract address"),
64
+ chain: str = typer.Option("eth", "-c", "--chain", help="Chain"),
65
+ ):
66
+ """Analyze rugpull risk for a token."""
67
+ if chain == "solana":
68
+ from .solana import check_solana_token, print_solana_token_report
69
+ report = check_solana_token(address)
70
+ print_solana_token_report(report)
71
+ return
72
+
73
+ from .rugpull import analyze_rugpull, print_rugpull_report
74
+
75
+ report = analyze_rugpull(address, chain)
76
+ print_rugpull_report(report)
77
+
78
+
79
+ @app.command("check-url")
80
+ def check_url_cmd(
81
+ url: str = typer.Argument(..., help="URL to check"),
82
+ ):
83
+ """Check if a URL is a known or suspected phishing site."""
84
+ from .phishing import check_url, print_phishing_report
85
+
86
+ report = check_url(url)
87
+ print_phishing_report(report)
88
+
89
+
90
+ @app.command()
91
+ def solana(
92
+ wallet: str = typer.Argument(..., help="Solana wallet address"),
93
+ ):
94
+ """Check Solana wallet — SOL balance + token holdings."""
95
+ from .solana import check_solana_wallet
96
+
97
+ print(f"\nšŸ›” Solana wallet scan — {wallet[:10]}...")
98
+ print("━" * 50)
99
+ report = check_solana_wallet(wallet)
100
+
101
+ print(f"\n šŸ’° SOL Balance: {report['sol_balance']:.4f} SOL")
102
+ print(f" šŸ“¦ Token accounts: {len(report['tokens'])}")
103
+
104
+ if report["tokens"]:
105
+ print("\n Token Holdings:")
106
+ for t in report["tokens"]:
107
+ if t["balance"] > 0:
108
+ print(f" • {t['mint'][:8]}...{t['mint'][-4:]}: {t['balance']:,.2f}")
109
+
110
+
111
+ @app.command()
112
+ def batch(
113
+ addresses_file: str = typer.Argument(..., help="File with addresses (one per line)"),
114
+ chain: str = typer.Option("eth", "-c", "--chain", help="Chain"),
115
+ mode: str = typer.Option("honeypot", "-m", "--mode", help="Mode: honeypot, approvals, rugpull"),
116
+ ):
117
+ """Batch check multiple addresses from a file."""
118
+ from pathlib import Path
119
+
120
+ path = Path(addresses_file)
121
+ if not path.exists():
122
+ print(f"File not found: {addresses_file}")
123
+ sys.exit(1)
124
+
125
+ addresses = [line.strip() for line in path.read_text().splitlines() if line.strip()]
126
+ print(f"\nšŸ›” Batch {mode} check — {len(addresses)} addresses on {chain}")
127
+ print("━" * 50)
128
+
129
+ for i, addr in enumerate(addresses, 1):
130
+ print(f"\n[{i}/{len(addresses)}] {addr[:10]}...")
131
+ if mode == "honeypot":
132
+ if chain == "solana":
133
+ from .solana import check_solana_token, print_solana_token_report
134
+ report = check_solana_token(addr)
135
+ print_solana_token_report(report)
136
+ else:
137
+ from .honeypot import check_honeypot, print_honeypot_report
138
+ report = check_honeypot(addr, chain)
139
+ print_honeypot_report(report)
140
+ elif mode == "rugpull":
141
+ if chain == "solana":
142
+ from .solana import check_solana_token, print_solana_token_report
143
+ report = check_solana_token(addr)
144
+ print_solana_token_report(report)
145
+ else:
146
+ from .rugpull import analyze_rugpull, print_rugpull_report
147
+ report = analyze_rugpull(addr, chain)
148
+ print_rugpull_report(report)
149
+ elif mode == "approvals":
150
+ from .approvals import scan_approvals, print_approval_report
151
+ results = scan_approvals(addr, chain)
152
+ print_approval_report(results, addr)
153
+
154
+
155
+ @app.command()
156
+ def version():
157
+ """Show version."""
158
+ print(f"CryptoShield v{__version__}")
159
+
160
+
161
+ def main():
162
+ app()
163
+
164
+
165
+ if __name__ == "__main__":
166
+ main()