Skip to content

Development

thaneye edited this page Oct 26, 2026 · 4 revisions

Development

Running the tests and looking after the data files. To contribute, read CONTRIBUTING.md first.

  • public/data/known-addresses.js is the built-in wallet list (exchanges and services): edit it directly. Label lists you import in the workspace add to it without changing the file; a name is a claim, not proof.
  • python tools/fetch_fixtures.py refreshes the public-chain fixtures in test/fixtures used by the tests.
  • python tools/build_packs.py --refresh rewrites the label packs the site ships (public/packs/) from the current OFAC list, the current UK Sanctions List, the pinned Ransomwhere release and the newest mining pools list; commit the result (--download --download-ransomwhere --download-miningpools does the same by naming the sources). See Labels, tags and packs.
  • Weekly refresh of the shipped packs. .github/workflows/refresh-packs.yml runs python tools/build_packs.py --refresh every Monday (and on demand: Actions > Refresh label packs > Run workflow). It downloads every source again, rebuilds each pack on its own (one that fails keeps its old files and fails the run, so GitHub tells you, while the others are still refreshed), runs the unit and tool tests on the new files, and opens a pull request named Refresh the shipped label packs that lists the wallets added, removed and renamed, with the text from the sources shown only as code. It never pushes to the main branch: merging the pull request publishes it. It also says when Ransomwhere has a newer release on Zenodo, which is a decision for a person (read the record and licence, then change RELEASE in tools/make_label_pack_ransomwhere.py). It needs Settings > Actions > General > Workflow permissions > Allow GitHub Actions to create and approve pull requests (also an organisation setting); without it the branch automation/refresh-packs is still pushed and the run tells you to open the pull request by hand. GitHub stops scheduled workflows in a repository with no activity for 60 days; a manual run starts it again. To add a source: write tools/make_label_pack_<name>.py (read the file, check every address, return the pack), a build_<name>() in tools/build_packs.py, and one entry in its SOURCES list; the workflow needs no change. A source whose licence or terms are not settled does not go in.
  • node tools/hopline-cli.js reads a saved workspace and prints its analysis as JSON (evidence summary, detections, peel chains, the facts about one vertex), makes the text to give an AI assistant, and checks the ids in an assistant's answer against the evidence. It never opens a connection. See docs/interface.md.
  • The benchmark measures each guess against data where the answer is known. node test/benchmark/run.js measures the committed cases and prints the results (--write-docs rewrites docs/benchmark-results.md); node --test fails when a number falls below its floor in test/benchmark/floors.json, so a change to the rules cannot quietly make a guess worse (move a floor only with the result that justifies it, in the same commit). python tools/bench/make_regtest.py --out test/benchmark/cases/regtest-v1 makes the cases again from the seed with Bitcoin Core in Docker (about half an hour); the committed cases record the seed, the node version and the image digest. node test/benchmark/base-rates.js counts how often each flag fires on a sample of the real chain (python tools/bench/fetch_mainnet_sample.py makes a new sample from a public API), node test/benchmark/trace.js follows the money from the start of a documented case with each auto-expand rule and replays it from a recording (--record asks the API again), and python tools/bench/make_wallet_case.py turns the public descriptors of real wallets on signet or testnet4 into a case (see docs/benchmark-wallets.md). See Accuracy and docs/benchmark.md.
  • Unit tests: node --test "test/*.test.js" (Node 20+). Browser tests: pip install pytest playwright && playwright install firefox, then python -m pytest test/e2e (the API is mocked from the fixtures, so no network is needed). Lookup proxy tests: python -m pytest test/proxy. A check of the backup server against the real mempool.space and Blockstream.info (it uses the network, about 30 requests, and is off unless asked): HOPLINE_LIVE=1 node --test "test/live/*.test.js". Tool tests (the report verifier, the OFAC label pack): python -m pytest test/tools.

Clone this wiki locally