Find historical native SOL transfers near a target USD value, using Bitquery's indexed Solana data.
You give it a date, a dollar amount, and a rough local time. It converts the dollar target into a SOL range at that day's price and returns matching native transfers, ranked by how close they are to the target. It queries Bitquery's index over narrow time windows rather than crawling the chain over RPC, so a lookup is a handful of API calls.
- Convert the USD target into a SOL amount using the historical SOL/USD price (auto-fetched, or
--sol-price-usd). - Build a
±tolerance%range around it. - Try each offset in
--timezone-offsetsin order, stopping at the first window that returns clean matches - Run one Bitquery
transfersquery per window, filtered server-side by time and amount. - De-duplicate, keep only plain system transfers (see below), score by distance from the target, write JSON.
- Python 3.10+
- A Bitquery access token
Get a token: https://account.bitquery.io/user/api_v2/access_tokens
cp .env.example .env # PowerShell: Copy-Item .env.example .envSet BITQUERY_TOKEN in .env; everything else has defaults. Optionally install for a soltrail command:
pip install -e . # then: soltrail --helpOr run the script directly, no install needed:
python scan_solana_bitquery.py --help# uses defaults from .env
python scan_solana_bitquery.py
# override on the command line
python scan_solana_bitquery.py --date 2026-04-15 --target-usd 200 --max-results 10
# a specific local window and timezone
python scan_solana_bitquery.py --date 2026-04-15 --target-usd 200 \
--local-window-start 11:45:26 --local-window-end 11:47:59 --timezone-offsets 3
# not sure about the timezone? try several, in order
python scan_solana_bitquery.py --date 2026-04-15 --target-usd 200 \
--local-window-start 11:46:07 --local-window-end 11:48:33 --timezone-offsets 0,3,5Add -v for debug logging or -q to only show warnings. Diagnostics go to stderr; results are the JSON file.
| Option | Description |
|---|---|
--date |
UTC date in YYYY-MM-DD format. |
--target-usd |
Target transfer value in USD. |
--tolerance-pct |
Allowed percentage deviation around the target value. |
--max-results |
Maximum number of matches to save. |
--query-limit |
Maximum Bitquery transfer rows to request per window. |
--local-window-start |
Local start time in HH:MM or HH:MM:SS. |
--local-window-end |
Local end time in HH:MM or HH:MM:SS. |
--timezone-offsets |
Comma-separated UTC offsets to try, e.g. 0,3,5. |
--sol-price-usd |
Manual SOL/USD price override. |
--include-non-pure-transfers |
Disable the strict pure-transfer filter. |
-v / -q |
Verbose / quiet logging. |
Run python scan_solana_bitquery.py --help for the full list. Most options also read from .env via SOLTRAIL_* keys; command-line flags win.
By default the scanner keeps only simple native SOL system transfers and drops anything that looks like swap/AMM plumbing. It decides from fields the same transfers query already returns - no second lookup - keeping a transfer only when:
- the instruction is a System Program
transfer, - the sender is also the signer and fee payer,
- there are no inner instructions,
- the account count and top-level instruction count are both small.
That removes most Pump.fun, Raydium, Jupiter and similar transfers. It's a heuristic, so eyeball anything important. Use --include-non-pure-transfers to see the raw candidates.
Results go to matches_<date>_bitquery.json. Each entry includes the signature, block time (UTC and in the matched timezone), SOL amount, estimated USD value, sender/receiver, the transaction-shape fields the filter used, and a closeness rank.
{
"date": "2026-04-15",
"sol_price_usd": 152.31,
"target_usd": 200.0,
"results": [
{
"signature": "5xEXAMPLE...signature",
"block_time": "2026-04-15T08:46:12Z",
"block_time_in_matched_timezone": "2026-04-15T11:46:12+03:00",
"amount_sol": 1.313110105,
"amount_usd_estimated": 200.01,
"usd_distance_abs": 0.01,
"source": "SenderPubkey...",
"destination": "ReceiverPubkey...",
"closeness_rank": 1,
"is_closest_match": true
}
]
}Each timezone window is one transfers query, tried in order until something matches - a lucky first guess costs a single call. Widen --query-limit only when the default window doesn't return enough clean candidates, and trim --timezone-offsets when you already know the zone.
Solana transaction data is public and this tool only reads it - use it for your own lookups and research, within Bitquery's terms of service.