Qbit Wallet 1.0.5
Release notes
Tagged 2026-10-28. This is the first public release of Qbit Wallet. Earlier versions were released from a private repository; their notes are in docs/releases/release-notes.md.
Install Qbit Wallet from the Chrome Web Store. The files attached here are for verifying the build, not for installing.
Sending and fees
- Coin selection ranks inputs by value after the per-input fee, so sends no longer pull in small inputs that cost more than they add or report "Insufficient balance" when the balance covers the payment.
- Sends, send-all and recovery sweeps stay within the standard transaction size. Send-all uses the highest-value inputs that fit and says what is left behind; recovery sweeps split into value-balanced batches.
- The wallet spends confirmed outputs and its own unconfirmed change, and no longer spends unconfirmed outputs received from others.
- A fee bump is refused when a later payment from the account depends on the original transaction, instead of silently cancelling that payment.
- A fee bump is bound to the transaction the account signed.
- Inputs of a just-broadcast transaction stay reserved, and a send whose broadcast result is unknown is reconciled instead of reported as failed. A website send rejected after signing releases its inputs straight away.
Accounts with many outputs
- An address holding more outputs than the explorer will list shows its total balance from the address summary, labelled as such, instead of 0. The wallet works out the spendable outputs from the address history, can consolidate them in standard-size batches, and can migrate them during recovery. See
docs/explorer-utxo-limit.mdand the known limitations below.
Websites and approvals
- Phishing blocking works under Manifest V3: navigations to denylisted sites are blocked, a click on a denylisted link always lands on the warning page, and Proceed lets the site load for the rest of the browser session. Even after Proceed, a denylisted site and its subdomains get no wallet provider, and the approval screens only let the user reject their connection and signing requests. This includes a subdomain whose name is not valid DNS, such as
a_b.<site>. - Each approval carries an id, so an approval window can settle only the request it shows. Unlocking the wallet settles only the unlock request.
- Website sessions are bound to the origin Chrome reports for the connection, and only the wallet's own pages can open UI connections.
Websites and integrators
Some requests that 1.0.4 accepted are now refused or answered differently.
signPsbtandsignPsbtsrefuse the following before the approval opens and before any signature counter moves:- an input whose
PSBT_IN_SIGHASH_TYPEis anything but the default (1.0.4 ignored the field and signed with the default); - an output other than P2MR, OP_RETURN or P2A, which qbit Core does not allow;
- a malformed PSBT: non-canonical compact sizes, malformed proprietary keys, out-of-range amounts, outputs worth more than the inputs, or duplicate keys;
- a PSBT over 16 MiB, or with more than 131,072 inputs, outputs and map entries combined;
- options that are not an object, carry a key other than
chainandautoFinalized, or have a non-booleanautoFinalized. These fail with-32602. 1.0.4 ignored unknown keys such astoSignInputsand signed every matching input.
- an input whose
- A
signPsbtscall without one options entry for each of its 1 to 20 PSBTs fails with-32602instead of4901. sendQbitreports an unknown broadcast outcome with the new error-32010anddata: { outcome: 'unknown', chain, txid }. The website should look that transaction up instead of retrying, which could pay twice. A transaction the wallet's follow-up lookup finds resolves with its txid. Seedocs/api/sign-transaction.md.pushTx,pushPsbt,signPsbtandsignPsbtsrefuse a transaction that spends an input a recent broadcast of another transaction spent, so a pending transaction cannot be replaced through them.- A second website request for a transaction that another request is already sending is refused.
- A website PSBT is finalized only when the wallet's signatures complete it. With
autoFinalizedomitted, a PSBT the wallet cannot complete comes back signed but not finalized. An explicitautoFinalized: truethat the wallet cannot meet is refused with-32602before the approval. - Some PSBTs that 1.0.4 could not finalize now finalize, such as one with another key's signature on the account's input. A finalized PSBT keeps the input fields qbit Core keeps, including the non-witness UTXO and unknown and proprietary fields. The extracted transaction is unchanged.
signMessagerefuses a message containing an unpaired UTF-16 surrogate.verifyMessagereturns false for such a message, and for a proof address that is not in its canonical lowercase spelling.qbit:URIs on the receive screen encode spaces in the label as%20.- The explorer client from the npm SDK behaves differently:
- It follows no redirects.
- Each attempt must receive the whole response, body included, within 15 seconds, so a very large history page on a slow connection can fail where 1.0.4 was only slow.
- It no longer re-sends a transaction after a timeout, network error or server error. The wallet looks the transaction up instead.
App Center
- The DApp Center is now the App Center in every locale. Its pool entries are now "Qbit Pool" and "Qbit Testnet Pool". They open
https://qbit.org/poolandhttps://qbit.org/pool?network=testnet4instead of prismpool.io.
Keys and vault
- Unlocking no longer replaces the stored vault while the keyrings rebuild, and a failed account or keyring change no longer rolls the vault back to an older copy. Post-quantum signing counters only move forward.
Recovery migration
- A failed migration step shows an error code and details that can be copied into a support request.
Repository and release
- The wallet workspace packages are private and are not published to npm. Security reporting goes through
SECURITY.md. - Release-gate, risk-register and privacy docs describe the controls as they are enforced.
- CI and the Playwright gate run on pull requests into release branches, the release token is kept away from install-time code, and dependency advisories are cleared.
- The SDK and PQC packages now come from npm:
@qbit-oss/pqc,@qbit-oss/protocoland@qbit-oss/api0.1.0, published with provenance from the signedv0.1.0tags of the public Qbit-Org repositories. The repository no longer has Git submodules.
Known limitations
- A website broadcast through
pushTxorpushPsbtwhose result is unknown, after a timeout, a server error or a lost connection, comes back to the website as an ordinary error, and its inputs are not reserved. A website that treats it as failed and asks for a new transaction can make the user pay twice. 1.0.4 behaved the same. The wallet's own sends look the transaction up instead, andsendQbitrejects with-32010naming the transaction to check. - For an address over the explorer's limit, the balance card's details show Available as 0 and the whole balance as Unavailable, although the spendable amount is not known. The send screen shows it as unknown.
- Input reservations and send claims are kept in memory only. A restart of the wallet's background, from a browser restart, a crash or an extension update, drops them. Until the explorer shows a just-sent transaction, a new send can then pick its inputs and conflict with it. Retrying a send from the wallet re-sends the same transaction. A website
sendQbitcut off during its broadcast gets a disconnect, not an "outcome unknown" error. - Consolidate an account that is over the explorer's limit before starting recovery. Once a migration has begun, consolidation is refused and the migration cannot be cancelled, and a source whose history is too long to read stops the whole migration from being prepared. See
docs/explorer-utxo-limit.md.
Verifying this release
- Commit:
7ced9979018c6671b028ae0d899d1afca02b515c. The tagv1.0.5is signed with OpenPGP key05A1 4A41 5C26 F421 6DC2 54FE 52D5 CC55 7D76 4586. qbit-chrome-mv3-v1.0.5.zipwas built from that commit by CI run 40722662041, which also checked that two clean builds are byte-identical. Its SHA-256 isa209c86146c275d12ad9f25b82f9e8efe5941685a7241ed5943668d3c1e90cb4.qbit-chrome-mv3-v1.0.5.zip.manifest.jsonlists the size and SHA-256 of every file in the ZIP.
The 1.0.5 build writes the path of the directory it was built in into background.js, in two places. A rebuild in any other directory therefore differs from this ZIP in background.js; every other file matches.
The Chrome Web Store package was built on another machine. Against this ZIP, its background.js differs only in that path, and its manifest.json has a different author email plus the update_url that the store adds. The store also adds _metadata/verified_contents.json. The other 69 files are byte-identical.
To rebuild with Node.js 22.22.3 (from .nvmrc), Corepack and unzip:
git clone --branch v1.0.5 https://github.com/Qbit-Org/qbit-wallet.git
cd qbit-wallet
corepack pnpm install --frozen-lockfile
corepack pnpm build:repro:extension
In apps/extension/dist/, the rebuilt qbit-chrome-mv3-v1.0.5.zip.manifest.json should differ from the one attached here only in the ZIP's own hash and size and the background.js entry. See docs/reproducible-builds.md.