Skip to content

Releases: m0wer/neutrino-api

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 02 Jun 21:50
a0f6b4e

Added

  • Watched-only mempool tracker (MEMPOOL_ENABLED). The daemon now
    subscribes to every connected peer's incoming P2P messages, fetches each
    announced transaction, and records the ones that pay or spend a watched
    address. Unconfirmed UTXOs are surfaced in the existing /v1/utxos
    endpoint with height: 0, unconfirmed spends are overlaid on
    /v1/utxo/{txid}/{vout} via new mempool_* fields, and watched mempool
    txs can be fetched verbatim from a new /v1/tx/{txid} endpoint. Tracker
    state is in-memory only; after each successful rescan pass it evicts
    precisely the entries that just confirmed on-chain (rather than wiping
    the whole view, which would drop still-unconfirmed entries because
    mempool peers do not reliably re-announce already-acked txs). A 14-day
    TTL sweeps stale entries; RBF replacements automatically evict the
    prior entry.
    • New config: MEMPOOL_ENABLED / --mempool (default: true) toggles
      the tracker.
    • New request flag: include_mempool on /v1/utxos (request body) and
      on /v1/utxo/{txid}/{vout} (query string), default true. Set to
      false to receive only the chain-only view.
    • /v1/status gains mempool_enabled and (when enabled) a mempool
      object reporting tracker counts (entries, utxos, spends,
      peers).
    • Privacy model: the daemon asks every peer for every announced tx
      rather than only those matching a local heuristic, so peers cannot
      learn which addresses the operator cares about. The bandwidth cost
      is small because we only fetch the tx body once per inv (deduped by
      txid across peers) and discard txs that don't touch a watched
      script. Backed by a fork patch on lightninglabs/neutrino that
      stops dropping MSG_TX advertisements when the local node hasn't
      asked the peer to relay txs.
  • Add a production-ready systemd service example in README for running the
    neutrinod binary directly on Linux hosts (including Raspberry Pi), with a
    signet-oriented configuration example.

Changed

  • Docker image publishing now includes linux/386, linux/arm/v7, and
    linux/arm/v6 in addition to linux/amd64 and linux/arm64, expanding
    compatibility to 32-bit x86 and broader 32-bit ARM Linux systems.
  • Release binary matrix now includes linux-386, linux-armv7,
    linux-armv6, and windows-arm64 artifacts in addition to the previous
    linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, and
    windows-amd64 outputs.
  • README now documents a signet Docker run example using
    LISTEN_ADDR=0.0.0.0:38334 and host port mapping 38334:38334.
  • Bump the lightninglabs/neutrino fork to
    0d5f911 (m0wer/neutrino), which gates the relaxed MSG_TX
    relay behaviour behind the new Config.MempoolEnabled flag instead
    of unconditionally enabling it.

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 30 Apr 09:38
d76dbf6

Fixed

  • Preserve earliest last_start_height across incremental rescans.
    Previously, every call to Rescan() (including auto-sync passes that
    start at last_scanned_tip + 1) overwrote the persisted
    last_start_height with the most recent invocation's start. This
    destroyed the wallet's coverage record on disk: clients use
    last_start_height together with last_scanned_tip to decide whether
    the daemon has already scanned the requested lookback window and skip
    redundant full rescans. The bug forced a full re-scan on every CLI
    invocation, which manifested as a ~12 s rescan even when the daemon
    had already scanned the entire requested range. LastStartHeight is
    now only lowered (when the new start is earlier or no scan has ever
    run); incremental scans no longer narrow the recorded coverage.

Added

  • Continuous background sync of watched addresses (AUTO_SYNC_WATCHED).
    The daemon now subscribes to block-connected notifications from the chain
    service and incrementally scans every new block for all watched addresses
    in the background, keeping the persisted UTXO set up-to-date in real time.
    After the initial /v1/rescan, subsequent /v1/utxos queries return
    immediately without requiring clients to re-trigger a rescan, and the
    daemon also catches up on every restart so wallet startup is instant
    even after extended downtime.
    • New config: AUTO_SYNC_WATCHED / --auto-sync-watched (default: true)
      enables the auto-sync goroutine.
    • New config: AUTO_SYNC_INTERVAL_SEC / --auto-sync-interval (default:
      30) sets the fallback poll interval used while waiting for initial
      header sync and as a safety net if block-notification subscription is
      unavailable.
    • Auto-sync skips when a manual rescan is already running and only starts
      after the chain service reports IsCurrent() == true to avoid scanning
      against an incomplete header chain.

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 09 Apr 15:13
c410cc1

Changed

  • Replace HTTP header import with CDN compact filter (cfilter) prefetch.
    Block headers and filter headers are now synced exclusively via P2P (trusted),
    while compact block filters can be bulk-downloaded from a block-dn CDN and
    verified against the P2P-synced filter headers before storage. This provides
    a better trust/performance balance: headers come from P2P consensus, filters
    are cryptographically verified against those headers, and the CDN is used
    only as untrusted transport for large filter data.
    • New config: CFILTER_CDN_AUTO / --cfilter-cdn-auto (default: true)
      enables automatic cfilter download from block-dn after P2P header sync.
    • New config: CFILTER_CDN_URL / --cfilter-cdn-url overrides the
      auto-resolved block-dn base URL.
    • Removed config: HEADER_IMPORT_AUTO, HEADER_IMPORT_BLOCK_URL,
      HEADER_IMPORT_FILTER_URL and their corresponding CLI flags.
    • Removed header import fallback retry logic from chain service startup.
    • CDN filters are downloaded in 2000-filter chunks, parsed from CompactSize
      varint binary format, and verified via ChainService.ImportCFilters().
    • Add ImportCFilter() and ImportCFilters() methods to the neutrino fork
      for verified bulk cfilter import.

Fixed

  • CDN chunk bounds now floor-align to include the containing chunk.
    Previously, when the prefetch start height did not align to a chunk boundary,
    the first available chunk was skipped, leaving a gap that required P2P
    fallback. The start is now floor-aligned so the chunk containing the
    requested start height is always downloaded.
  • CDN prefetch continues past failed chunks instead of aborting.
    Previously, any CDN chunk failure (verification mismatch or HTTP error)
    would abort the entire CDN prefetch, forcing P2P to fetch all remaining
    filters. Now, failed chunks are retried with exponential backoff, and if
    retries are exhausted the chunk is skipped. CDN continues with subsequent
    chunks, and P2P fills only the specific gaps. CDN prefetch is aborted
    only after 3 consecutive failures.
  • Pin neutrino fork dependency to pushed commit.
    Replace local path replace directive with versioned pseudo-version
    pointing to m0wer/neutrino@c1b598b97446.

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 08 Apr 10:41
42ae2e9

Fixed

  • Fix .onion peer hostname handling in ban checks by patching the neutrino
    ban manager parser to support Tor v2/v3 addresses, so discovered onion peers
    no longer trigger unsupported IP type parse errors.

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 07 Apr 13:57
421c476

Added

  • Auto-TLS and API token authentication: The server now generates a self-signed TLS certificate (EC P-256) and a random API token on first start, protecting against eavesdropping and unauthorized access. Credentials are persisted in the data directory.
  • Add --no-auth / NO_AUTH=true flag to disable TLS and token authentication (for development/regtest environments).
  • Add --reset-auth flag to regenerate TLS certificate and auth token, and clear privacy-sensitive data (watched addresses, UTXOs).
  • Add GET /v1/version endpoint returning {"version": "..."} for lightweight version diagnostics.
  • Include version and watched_addresses fields in GET /v1/status responses.
  • Include watched_addresses and server_version in GET /v1/rescan/status responses.
  • Add X-Neutrino-Version response header on JSON API responses.
  • Docker image major-version tags (e.g., ghcr.io/m0wer/neutrino-api:1): Users can pin to a major version for automatic minor/patch updates without breaking changes.

Changed

  • BREAKING: Server now uses HTTPS and requires authentication by default. Previously the server listened on plain HTTP with no authentication. It now auto-generates a TLS certificate and auth token, and requires Authorization: Bearer <token> on all requests. See the migration guide below.

Migration guide (upgrading to this version)

Existing deployments that relied on unauthenticated plain HTTP access will break after upgrading. Choose one of the following approaches:

  1. Adopt TLS + auth (recommended for production): After starting the upgraded server, find the auto-generated auth token in <datadir>/auth_token. Update your clients to use HTTPS and include the Authorization: Bearer <token> header. If using self-signed TLS, configure your client to trust <datadir>/tls.cert.

  2. Disable auth (development/regtest only): Set NO_AUTH=true (environment variable) or pass --no-auth to restore the previous unauthenticated HTTP behavior. This is already set in the provided docker-compose.yml for the regtest environment.

  3. Pin your Docker image to a major version tag to avoid future breaking changes from automatic pulls. Use ghcr.io/m0wer/neutrino-api:0 for the pre-auth behavior or ghcr.io/m0wer/neutrino-api:1 once v1.0.0 is released.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 06 Apr 08:07
888d1ff

Added

  • Two-phase startup for faster initial sync with Tor setups: Added --clearnet-initial-sync / CLEARNET_INITIAL_SYNC (default: true). When Tor is configured, the node now syncs block headers and filter headers over clearnet first, then restarts the chain service in Tor mode for privacy-sensitive operations.

Changed

  • Compact filter prefetch is now opt-in: --prefetchfilters / PREFETCH_FILTERS now defaults to false to avoid downloading and storing the full historical filter set on first startup.
  • New prefetch lookback control: Added --prefetchlookback / PREFETCH_LOOKBACK (default: 105120, about 2 years). When prefetch is enabled and prefetchstart=0, the prefetch start height is auto-computed as tip - lookback.

Fixed

  • Spent UTXO detection in bulk endpoint: POST /v1/utxos could return already-spent UTXOs because the batch MatchAny filter scan missed spending blocks in certain cases. Added a per-UTXO spend verification pass after the main scan that uses single-script filter.Match (the same approach used by the reliable GET /v1/utxo/{txid}/{vout} endpoint) to catch any spends missed by the batch scan.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 19 Mar 08:04
83a2705

Added

  • Persistent state across restarts (rescan_state.db): Watched addresses, UTXO set, and rescan metadata (last scanned tip, start height) are now persisted to a separate bbolt database. On restart, the server restores its previous state so UTXOs are available immediately without re-scanning. The state store uses three buckets (watched_addrs, utxo_set, rescan_meta) and is optional (nil = no persistence) for backward compatibility with tests.
  • Incremental rescan: When a rescan is requested with a start_height within the already-scanned range, the scan starts from LastScannedTip+1 instead of re-scanning the entire range. If already up-to-date, returns immediately. This avoids redundant 52k+ block rescans after restarts.
  • Rescan fallback to watched addresses: POST /v1/rescan with an empty addresses field now falls back to all previously watched addresses instead of silently doing nothing.
  • HTTP request/response logging middleware: Every API call is logged with method, path, status code, and duration. 4xx/5xx responses log at WARN level; 2xx at INFO level.
  • Rescan progress logging: During block scanning, progress is logged every 10 seconds with blocks scanned/total, percentage, current height, blocks/sec, estimated time remaining, and filter match count. A final summary includes total blocks, duration, speed, filter matches, and detailed UTXO accounting (found/added/removed).
  • Rescan handler request logging: POST /v1/rescan now logs start_height, address count, and outpoint count at INFO level.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 17 Mar 12:05
846ed3a

Added

  • Add reproducible release flow for neutrinod binaries with deterministic Go build flags and SOURCE_DATE_EPOCH.
  • Add scripts/release-build-sign.sh to build release binaries locally, generate SHA256SUMS, and create a detached GPG signature.
  • Add scripts/verify-release-build.sh as a one-command local reproducibility check against the signed digest.
  • Add release signature infrastructure under signatures/ with trusted key list and m0wer public key.
  • Add addPeers setting, similar to connectPeers, that allows specifying peers to connect to without disabling peer discovery.

Changed

  • Update release workflow to rebuild binaries in CI, verify checksums against committed signatures/<version>/SHA256SUMS, verify SHA256SUMS.asc, and upload binaries plus signed digest files to GitHub releases.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 11 Mar 09:33
820d10a

Added

  • Add GET /v1/rescan/status endpoint that returns {"in_progress": bool}, allowing clients to poll until a background rescan completes instead of using a fixed sleep.
  • Add block_height to UTXOSpendReport for more efficient scans.

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 09 Jan 10:11
421b509

Fixed

  • Fixed UTXO endpoint to return HTTP 404 (Not Found) instead of 500 (Internal Server Error) when UTXO is not found
  • Added proper error type handling for API errors:
    • NotFoundError returns HTTP 404
    • BadRequestError returns HTTP 400
    • Invalid address or txid parameters now return 400 instead of 500