Skip to main content

On-chain AML pattern detection tool for cryptocurrency transactions

Project description

Onchain AML

Ko-fi

Buy Me A Coffee

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chain_scanner-0.1.0.tar.gz (47.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chain_scanner-0.1.0-py3-none-any.whl (55.0 kB view details)

Uploaded Python 3

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

Hashes for chain_scanner-0.1.0.tar.gz
Algorithm Hash digest
SHA256 448876dfd8403535aa7c2d6bb472805030ede6ce994793d2067d63578364373c
MD5 2d93e9f2bd09e74a662e4b1c833cdc44
BLAKE2b-256 cc8db4cc406708009e3927c4a6ce1e7bfe04f79e88f5b21dc6474a55cc9b8d2f

See more details on using hashes here.

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

Hashes for chain_scanner-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 148e088b4914c2190ca723b9aeefb3d735c521b688aaa5ba84a70ceb71ed5861
MD5 ba2fe571f9681eba8aa4cca18d7f8491
BLAKE2b-256 19f43a78db254a2d87384bfc1cd3bb21ab18bc35580821e27ea9dcdb01a5128a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page