A Python-based backend system that identifies "twin" transactions across different blockchains by matching metadata from bridge protocols like deBridge, Houdini Swap, THORSwap, and Across Protocol.
- Multi-Protocol Support: Tracks transactions from deBridge (DLN), Houdini Swap, THORSwap, Across Protocol, and Stargate V2
- Cross-Chain Indexing: Monitors Ethereum, Arbitrum, Solana, BSC, and other chains
- Probabilistic Matching: Advanced algorithm to correlate send/receive events based on time, value, and asset type
- REST API: FastAPI-powered endpoints for real-time tracking
- Automated Polling: Background scheduler polls blockchain explorers every 30 seconds
- PostgreSQL Storage: Efficient storage with optimized indexes for fast queries
βββββββββββββββββββ
β FastAPI β β REST API Server (Port 8000)
β /api/tracker β
ββββββββββ¬βββββββββ
β
ββββββββββ΄βββββββββββββββββββββββββ
β APScheduler (Background) β
β - Poll events (30s) β
β - Run matching (15s) β
ββββββββββ¬βββββββββββββββββββββββββ
β
ββββββββββ΄βββββββββββββββββββββββββ
β Event Fetchers β
β - Web3.py (EVM chains) β
β - Etherscan API β
β - Alchemy RPC β
ββββββββββ¬βββββββββββββββββββββββββ
β
ββββββββββ΄βββββββββββββββββββββββββ
β Matching Engine β
β - Time delta β€ 5 min β
β - Value delta β€ $50 β
β - Token equivalence β
ββββββββββ¬βββββββββββββββββββββββββ
β
ββββββββββ΄βββββββββββββββββββββββββ
β PostgreSQL Database β
β - bridge_events β
β - matched_transactions β
βββββββββββββββββββββββββββββββββββ
- Python 3.9+
- PostgreSQL 13+
- API Keys:
- Etherscan API Key
- Alchemy API Key
- Solscan API Key (for Solana support)
# Clone the repository
cd bridgescan
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt# Install PostgreSQL (Ubuntu/Debian)
sudo apt update
sudo apt install postgresql postgresql-contrib
# Start PostgreSQL
sudo systemctl start postgresql
# Create database and user
sudo -u postgres psqlIn PostgreSQL shell:
CREATE DATABASE bridgescan;
CREATE USER bridgescan WITH PASSWORD 'bridgescan';
GRANT ALL PRIVILEGES ON DATABASE bridgescan TO bridgescan;
\q# Copy example environment file
cp .env.example .env
# Edit .env with your API keys
nano .envUpdate these critical values:
ETHERSCAN_API_KEY=your_etherscan_key
ALCHEMY_API_KEY=your_alchemy_key
DATABASE_URL=postgresql://bridgescan:bridgescan@localhost:5432/bridgescan# Create database tables
python main.py --mode init-dbFull Mode (API + Scheduler):
python main.py --mode fullAPI Only:
python main.py --mode apiScheduler Only:
python main.py --mode schedulerThe API will be available at: http://localhost:8000
GET /api/tracker/liveQuery Parameters:
limit(int, default: 50): Maximum events to returnprotocol(string, optional): Filter by protocol namechain(string, optional): Filter by blockchainmatched_only(bool, default: false): Only return matched events
Example:
curl "http://localhost:8000/api/tracker/live?limit=10&protocol=debridge"Response:
{
"success": true,
"timestamp": "2026-01-14T10:30:00Z",
"data": {
"events": [...],
"recent_matches": [...],
"total_events": 10,
"total_matches": 5
}
}GET /api/eventsQuery Parameters:
event_type(string): "send" or "receive"protocol(string): Protocol namechain(string): Blockchain namelimit(int, default: 100)
GET /api/matchesQuery Parameters:
limit(int, default: 100)min_confidence(float, 0-1): Minimum confidence score
GET /api/statsReturns overall platform statistics.
GET /healthUnified data structure for all bridge events:
@dataclass
class BridgeEvent:
source_chain: str
source_tx_hash: str
source_timestamp: str # ISO 8601
token_sent: str
usd_value: float
sender_address: str
protocol: str
event_type: EventType # SEND or RECEIVE
destination_chain: Optional[str]
destination_address: Optional[str]matcher = BridgeMatcher(
time_tolerance_seconds=300, # 5 minutes
value_tolerance_usd=50.0,
min_confidence_score=0.7
)
matches = matcher.find_bridge_twins(pending_sends, pending_receives)Matching Criteria:
- β
Time Delta:
abs(send_time - receive_time) <= 300 seconds - β
Value Tolerance:
abs(send_value - receive_value) <= $50.00 - β Asset Match: Token equivalence (e.g., USDT β USDC)
β οΈ Special Rule: Houdini Swap ignores sender address matching
Confidence Score Calculation:
- Time similarity: 40%
- Value similarity: 35%
- Asset match: 20%
- Address match: 5%
Fetches events from multiple sources:
fetcher = BlockchainEventFetcher(config)
# Fetch deBridge events
events = fetcher.fetch_debridge_events(
chain='ethereum',
from_block=18000000,
to_block='latest'
)
# Fetch Across Protocol events
events = fetcher.fetch_across_events(
chain='arbitrum',
from_block=100000000
)python sample_fetcher.pyThis demonstrates:
- Connecting to Ethereum via Alchemy
- Fetching deBridge CreatedOrder events
- Fetching Across V3FundsDeposited events
- Parsing events with Web3.py
CREATE TABLE bridge_events (
id SERIAL PRIMARY KEY,
source_chain VARCHAR(50) NOT NULL,
source_tx_hash VARCHAR(100) UNIQUE NOT NULL,
source_timestamp TIMESTAMP NOT NULL,
token_sent VARCHAR(20) NOT NULL,
usd_value DOUBLE PRECISION NOT NULL,
sender_address VARCHAR(100) NOT NULL,
destination_address VARCHAR(100),
protocol VARCHAR(50) NOT NULL,
event_type VARCHAR(20) NOT NULL,
destination_chain VARCHAR(50),
matched BOOLEAN DEFAULT FALSE,
matched_twin_id INTEGER REFERENCES bridge_events(id),
matched_at TIMESTAMP,
raw_data TEXT,
created_at TIMESTAMP DEFAULT NOW()
);CREATE TABLE matched_transactions (
id SERIAL PRIMARY KEY,
send_event_id INTEGER REFERENCES bridge_events(id),
receive_event_id INTEGER REFERENCES bridge_events(id),
confidence_score DOUBLE PRECISION NOT NULL,
time_delta_seconds DOUBLE PRECISION NOT NULL,
value_delta_usd DOUBLE PRECISION NOT NULL,
matched_at TIMESTAMP DEFAULT NOW()
);| Protocol | Chains | Event Types |
|---|---|---|
| deBridge (DLN) | ETH, ARB, BSC | CreatedOrder, FulfilledOrder |
| Across Protocol | ETH, ARB, OP | V3FundsDeposited, V3FilledRelay |
| THORSwap | ETH, AVAX | Swap, Deposit |
| Stargate V2 | Multi-chain | OFTReceived |
| Houdini Swap | Multi-chain | Custom events |
All configuration is in config.py and can be overridden via environment variables:
# Matching parameters
TIME_TOLERANCE_SECONDS = 300 # 5 minutes
VALUE_TOLERANCE_USD = 50.0
MIN_CONFIDENCE_SCORE = 0.7
# Polling intervals
POLL_INTERVAL_SECONDS = 30
MATCH_INTERVAL_SECONDS = 15
# Starting blocks
ETHEREUM_START_BLOCK = 18000000
ARBITRUM_START_BLOCK = 100000000
BSC_START_BLOCK = 30000000View logs:
tail -f bridgescan.logCheck API health:
curl http://localhost:8000/health.env.example are samples. Replace them with your own keys.
Best Practices:
- Never commit
.envfile to version control - Use environment variables in production
- Rotate API keys regularly
- Use read-only API keys where possible
- Implement rate limiting in production
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py", "--mode", "full"]Create /etc/systemd/system/bridgescan.service:
[Unit]
Description=Bridgescan Bridge Tracker
After=network.target postgresql.service
[Service]
Type=simple
User=bridgescan
WorkingDirectory=/opt/bridgescan
Environment="PATH=/opt/bridgescan/venv/bin"
ExecStart=/opt/bridgescan/venv/bin/python main.py --mode full
Restart=always
[Install]
WantedBy=multi-user.targetContributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
MIT License - See LICENSE file for details
For issues and questions:
- GitHub Issues: [Your repo URL]
- Email: support@bridgescan.io
- Add Solana bridge support
- Implement WebSocket for real-time updates
- Add price oracle integration for accurate USD values
- Support for more bridge protocols
- Historical data analytics dashboard
- MEV detection and flagging