Skip to content

v1.2.2

Choose a tag to compare

@github-actions github-actions released this 29 Sep 14:50

Stabilization after 1.2.1: no new features. Found by testing the published
1.2.1 on a StartOS VM, a bug hunt of the tax engine, the imports and the AI
connector, and a privacy audit (2026-09-29). Each fix has a test that
failed before it.

Changed

  • The sidebar calculator is a little taller (owner's request): its keys
    are slightly longer, so it ends level with the Dashboard's Realized
    Gains/Losses card. The Sats Converter's price area is now the same height
    in Manual, Auto and Date, so the calculator no longer moves when you
    switch; in Date mode the day's price sits beside "Select date".

Fixes to tax figures

  • Changing a transaction's type no longer keeps the old type's fields.
    A Gift changed into a Sell stayed a "gift" and was missing from Form 8949
    and Schedule D; a withdrawal changed into an Income deposit reported the
    old lots' cost basis as the income instead of that day's value. (Only the
    AI connector or the API can change a type; the form locks it.)
  • A fee entered without its currency now counts. Adding a fee on its
    own (e.g. by the AI connector) left a Sell's proceeds and a Buy's cost
    basis without it, and took a withdrawal's BTC fee from the balance with
    no disposal or value. The fee now gets its type's currency (USD for Buy
    and Sell, else the account's) and is saved with it; entries already saved
    that way are fixed by the next recalculation (which needs that day's
    price, or the fee's value typed in, for a BTC fee).
  • Pay the AI adds as an Income deposit into Bank or Exchange USD is no
    longer valued at the BTC price
    ($5,000 became $250 million of income);
    likewise a Spent or Gift withdrawal from a USD account. Only BTC accounts
    are valued at the day's BTC price.
  • Dates given to the AI connector are read as when adding. Changing a
    transaction's date read it as UTC, so in the US a sale moved to Jan 1
    landed on Dec 31, in the previous tax year; a date alone is now midday in
    your tax timezone. A time ending in " UTC" is read as UTC (it was read in
    the tax timezone), and finding transactions by date uses days in your tax
    timezone.
  • A second Buy of the same amount at another price can be saved through
    the AI.
    A Buy of the same BTC amount within 48 hours was taken for a
    duplicate even at a different price, skipped, and could never be saved.
    It's now a possible duplicate the AI asks you about; only the very same
    buy (same amount and price) is skipped.
  • Export CSV then Import CSV keeps the order of same-time entries. The
    import put them in a fixed type order (moves before sales), which could
    change which coins a sale used and its gain; rows at the same time now go
    in the file's order (the export's is the ledger's). A hand-made file that
    lists a sale before the same-time buy paying for it is refused, and the
    message says to list the buy first.
  • Form 8949 line 2 "Totals" is filled. Each page now shows the totals of
    its own rows in (d), (e) and (h), which add up to the Schedule D line; it
    was left blank on the locked PDF, so it couldn't be typed in either.
  • A sale drawn from several lots no longer loses cents. Each lot's share
    of the proceeds was rounded on its own ($100.00 over three lots showed as
    $99.99 on Form 8949); the last share now takes the remainder.
  • A withdrawal of 1 satoshi more than you hold is refused, like a
    transfer or sale. It was accepted and left the balance at -1 sat.
  • A time with fractions of a second no longer lands in the wrong year.
    A sale entered (through the API or the AI connector) half a second after
    midnight on Jan 1 counted in the year before; times are now saved in
    whole seconds.
  • A Spent withdrawal changed into a Gift, Donation or Lost no longer keeps
    its proceeds
    , which the complete tax report printed in its Gifts
    section. (The network fee is still its own taxable disposal.)

Other fixes

  • The Sats Converter no longer shows "BTC Price: $0.00" without a price.
    With prices off it says "Prices off", after an error or for a day with no
    stored price "No price", and the USD field empties instead of keeping an
    old figure (BTC and sats still convert).
  • My Mempool not answering is an error, not "Prices off". With your
    Mempool chosen but missing or not answering (and the fallback off), the
    Dashboard said "Prices off"; it now says "Error", and hovering it shows
    why (e.g. install and start Mempool).
  • Clearer messages when no price is stored. A transfer's missing fee
    value names the form's Fee value (USD) field (and fee_usd for
    imports), and a new Spent withdrawal without proceeds is no longer told
    to "edit that transaction".
  • The complete tax report says where its prices come from. It claimed
    "the average market value at the time of disposal"; it now says values
    are the ones entered, a blank one comes from that day's stored daily
    price, and dates are in the tax timezone (named).
  • An import no longer freezes the whole app while it works. A CSV,
    River or AI-assistant import (or its preview) held up every other
    request, StartOS's health check included, for as long as it ran (10
    seconds in one test); that work now runs beside them.
  • The CSV import reads Excel's "CSV UTF-8" files. Their invisible
    byte-order mark made the import say "Missing required columns: date".
  • A River file row with one comma too many is that row's error. A
    trailing comma or an amount written 1,000.00 made the River import fail
    with a server error.
  • A River Sell whose Fee Currency is blank is no longer a fee short. A
    blank fee currency on a River Buy or Sell counts as USD, as River charges
    it, so the sale lands at River's Received Amount.
  • When BitcoinTX's address redirects (e.g. http:// to https://), the
    AI connector says so and which address to set in BTCTX_URL, instead of
    an unclear error or a blank price. It still never follows a redirect, so
    the AI key only goes to that address.
  • Keyboard focus shows in the Mac app on older macOS. On Safari before
    15.4 (macOS 10.15 to 12.2) no focus ring was drawn at all; the browser's
    own ring now stays there, and newer versions keep the gold one.

Privacy (docs/temp/privacy-audit.md)

  • The AI connector no longer writes request addresses to the AI app's log
    files; past-price lookups named your transaction dates there.
  • An .onion mempool address needs the proxy: it's refused without one (it
    was looked up through the normal DNS, which then saw the name).
  • An encrypted backup no longer passes through a plain copy in the system's
    temp folder, and a restore's decrypted file is owner-only from the moment
    it's written.
  • Making reports no longer logs how many transactions, disposals and lots
    each year has (now only at the DEBUG log level).
  • The Docker instructions start BitcoinTX reachable from your computer
    only (-p 127.0.0.1:8080:80), with a note to put it behind HTTPS for
    other devices; the old command sent your password and ledger unencrypted
    across your network. The AI connector warns once in its log when it talks
    to another machine over plain http:// (owner decision).
  • The encrypted backup's password is typed in a hidden field, twice: it
    was a plain pop-up that showed it and asked once, so a typo made a backup
    no one could open (owner decision).
  • Deleted transactions are erased from the database file (SQLite's secure
    delete), instead of staying readable in it and its copies until it was
    compacted.
  • Settings > Backup & Restore says BitcoinTX keeps a few unencrypted safety
    copies of its database in its data folder.
  • Responses no longer name the web server ("server: uvicorn"), and the
    Docker image's data folder is owner-only (it was writable by everyone).
  • The READMEs say that uvx downloads the AI connector from PyPI once,
    which sees your IP address and the version.
  • Settings (and StartOS's Price Source & Privacy action and instructions)
    name every public site BitcoinTX may contact (mempool.space and Coinbase
    were missing) and say the sites see your IP address and when BitcoinTX is
    open, never your transaction dates (owner decision).
  • Fewer requests to public price sites: the live price asks Kraken first
    and CoinGecko only if Kraken fails (CoinGecko refuses VPN and Tor users,
    so each refresh used to contact both), and the block height is kept for a
    minute like the price instead of being asked on every Dashboard visit
    (owner decision).
  • Restoring a backup in the app keeps the price settings in use, as it
    keeps your login and AI key: a backup from before a switch to Tor or Off
    brought back direct lookups of the public sites (owner decision).

Downloads

  • StartOS: btctx.s9pk. In StartOS, open Sideload and upload it; installs of earlier versions update in place.
  • macOS: BitcoinTX-macOS.dmg (or the .zip). The app is not signed by Apple: the first time, right-click (Control-click) BitcoinTX in Applications and choose Open; on macOS 15 or later, open it once, then go to System Settings > Privacy & Security and click Open Anyway.
  • Docker: ghcr.io/digimonk73/btctx-mcp:v1.2.2 (amd64 and arm64).
  • AI connector: uvx btctx-mcp==1.2.2 (PyPI); Settings → Connect an AI Assistant has it ready to paste.