On-chain AML pattern detection tool for cryptocurrency transactions
Project description
Onchain AML
On-Chain AML Pattern Detector
A local/offline AML pattern detection tool for cryptocurrency transactions. Supports Ethereum and Bitcoin, multiple data input methods, and provides both CLI and library interfaces.
All analysis runs locally - no data is sent to external servers.
Features
- Multi-chain support: Ethereum and Bitcoin
- Multiple data sources: JSON/CSV files, API (Etherscan), or local node
- 6 Detection modules: Mixers, sanctions, structuring, layering, privacy coins, bridges
- Risk scoring: 0-100 score with LOW/MEDIUM/HIGH/CRITICAL classification
- Flexible output: Terminal, JSON, or CSV reports
- Extensible: Easy to add new detectors and data sources
Installation
pip install git+https://github.com/cleonard2341/onchain-aml.git
Or install from source:
git clone https://github.com/cleonard2341/onchain-aml.git
cd onchain-aml
pip install -e .
Quick Start
Command Line
# Scan an address
chain-scanner scan 0x742d35Cc6634C0532925a3b844Bc9e7595f... --chain eth
# Scan from a file
chain-scanner scan-file transactions.json
# Check against sanctions list
chain-scanner check-sanctions 0x8589427373D6D84E98730D7795D8f6f8731FDA16
# Generate JSON report
chain-scanner scan-file data.json --output report.json --output-format json
# List available detectors
chain-scanner list-detectors
As a Library
from chain_scanner import Scanner
# Create scanner for Ethereum
scanner = Scanner(chain="ethereum")
# Scan transactions from a file
result = scanner.scan_file("transactions.json")
# Check the results
print(f"Risk Score: {result.risk_score}/100")
print(f"Risk Level: {result.risk_level}")
for flag in result.flags:
print(f" [{flag.severity}] {flag.type}: {flag.details}")
Detection Modules
| Detector | Description | Signals |
|---|---|---|
| Sanctions | OFAC/blocklist match | Address appears on sanctions list |
| Mixer | Known mixer services | Tornado Cash, Wasabi, CoinJoin, etc. |
| Structuring | Transaction splitting | Multiple txs just below reporting thresholds |
| Layering | Rapid fund movement | Funds hopping 3+ addresses within 48 hours |
| Privacy Coins | Anonymity-enhanced | RAILGUN, Aztec, privacy token bridges |
| Bridges | Cross-chain movement | Wormhole, Multichain, THORChain, etc. |
Risk Scoring
Each scan returns a risk assessment:
{
"address": "0x...",
"risk_score": 78, # 0-100
"risk_level": "HIGH", # LOW/MEDIUM/HIGH/CRITICAL
"flags": [
{
"type": "MIXER",
"severity": "HIGH",
"details": "Tornado Cash interaction"
}
],
"summary": "High risk patterns detected: mixer usage"
}
Risk Levels
| Level | Score | Description |
|---|---|---|
| LOW | 0-25 | Minor or no risk indicators |
| MEDIUM | 26-50 | Some risk indicators present |
| HIGH | 51-75 | Significant risk patterns detected |
| CRITICAL | 76-100 | Severe risk including sanctions matches |
Data Sources
File Input
result = scanner.scan_file("transactions.json") # JSON
result = scanner.scan_file("transactions.csv") # CSV
API Source (Etherscan)
scanner = Scanner(chain="ethereum")
scanner.use_api_source(api_key="YOUR_ETHERSCAN_API_KEY")
result = scanner.scan_address("0x...", fetch_transactions=True)
Custom Transactions
from chain_scanner import Scanner, Transaction
from decimal import Decimal
transactions = [
Transaction(
hash="0xabc...",
chain="ethereum",
from_address="0x111...",
to_address="0x222...",
value=Decimal("1.5"),
)
]
result = scanner.scan_transactions(transactions)
Configuration
from chain_scanner import Scanner, ScannerConfig
config = ScannerConfig()
config.structuring.threshold_usd = 10000
config.structuring.min_transactions = 3
config.risk_weights.mixer = 80
scanner = Scanner(chain="ethereum", config=config)
Or load from JSON:
chain-scanner --config config.json scan 0x...
Input File Formats
JSON
{
"transactions": [
{
"hash": "0x...",
"from": "0x...",
"to": "0x...",
"value": "1000000000000000000",
"blockNumber": 15000000,
"timeStamp": "1672531200"
}
]
}
CSV
hash,from,to,value,blockNumber,timeStamp
0x...,0x...,0x...,1000000000000000000,15000000,1672531200
Development
git clone https://github.com/cleonard2341/onchain-aml.git
cd onchain-aml
pip install -e ".[dev]"
pytest tests/ -v
License
MIT License - see LICENSE for details.
Disclaimer
This tool is for informational and research purposes only. It should not be used as the sole basis for compliance decisions. Always consult with legal and compliance professionals for AML/KYC requirements.
The address lists included are samples for demonstration. For production use, update sanctions and mixer lists regularly from official sources.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chain_scanner-0.1.0.tar.gz.
File metadata
- Download URL: chain_scanner-0.1.0.tar.gz
- Upload date:
- Size: 47.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
448876dfd8403535aa7c2d6bb472805030ede6ce994793d2067d63578364373c
|
|
| MD5 |
2d93e9f2bd09e74a662e4b1c833cdc44
|
|
| BLAKE2b-256 |
cc8db4cc406708009e3927c4a6ce1e7bfe04f79e88f5b21dc6474a55cc9b8d2f
|
File details
Details for the file chain_scanner-0.1.0-py3-none-any.whl.
File metadata
- Download URL: chain_scanner-0.1.0-py3-none-any.whl
- Upload date:
- Size: 55.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
148e088b4914c2190ca723b9aeefb3d735c521b688aaa5ba84a70ceb71ed5861
|
|
| MD5 |
ba2fe571f9681eba8aa4cca18d7f8491
|
|
| BLAKE2b-256 |
19f43a78db254a2d87384bfc1cd3bb21ab18bc35580821e27ea9dcdb01a5128a
|