v1.2.2
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 (andfee_usdfor
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://tohttps://), the
AI connector says so and which address to set inBTCTX_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
.onionmempool 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 plainhttp://(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
uvxdownloads 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.