Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ A `vX.Y.Z` tag runs `publish-npm.yml` (publishing `packages/wallet`, `packages/w

## [Unreleased]

## [0.9.0] - 2026-11-05

Hardening from the 0.9 audit: contract-reported token text is shown only when it is safe, pending
connection requests are bounded and expire, and the engine's timeouts and jitter run on the
injected timer and random source. Closes #99, #100, #101 and #102.

### Added

- `@qntx/wallet-engine`: untrusted contract text is checked before it is shown: a watched token's symbol must be printable (no control, bidi or zero-width characters, at most 32 code points) and its decimals an integer in 0..36 or the request fails with `-32602`; a non-ASCII symbol adds a `token-symbol-unicode` warning; simulated asset changes keep an unverified token's `symbol` and `decimals` only when they pass the same checks.
Expand All @@ -20,15 +26,19 @@ A `vX.Y.Z` tag runs `publish-npm.yml` (publishing `packages/wallet`, `packages/w
- `@qntx/wallet-chains`: BIP-322 script pushes longer than 252 bytes are rejected instead of mis-encoded.
- `@qntx/wallet-engine`: the Solana and EIP-1193 handlers share one session-event helper and the Solana sign path one request method.

- `@qntx/wallet-engine/connect`: the injected Solana Wallet Standard wallet now conforms to `@wallet-standard/base` and `@solana/wallet-standard-features` (typed, no cast): every feature is versioned `1.0.0`, `solana:signTransaction` and `solana:signAndSendTransaction` declare `supportedTransactionVersions: ["legacy", 0]` and are variadic (N inputs become one host request, one approval), `signMessage` returns `[{ signedMessage, signature, signatureType }]`, `standard:events` `on` returns an unsubscribe function, and each input's `account` and `chain` are forwarded. The handler rejects an account other than the session's (`4100`), an unknown or mixed chain (`-32602`) and a chain the session is not authorized for (`4100`); sign-and-send needs a chain and returns raw signature bytes.
## [0.8.1] - 2026-11-05

A native wallet can unlock again after it locks, without restarting the app. This release also
shipped the work merged since 0.8.0 — the local phishing list, transaction simulation and the
remaining in-app browser methods — including the breaking engine changes listed below; they were
missing from these notes when the release was cut.

### Added

- `@qntx/wallet-engine/connect`: the remaining browser methods.
- `wallet_addEthereumChain` answers `4902` for a chain the wallet does not enable, otherwise `null`; a chain outside the session goes through the `network` connection approval without becoming current. The page's `rpcUrls` are validated for shape only and never used.
- `wallet_watchAsset` (ERC-20) reads `symbol` and `decimals` on-chain in a new factor-free `watch-asset` request, shows them with a `token-impersonation` danger when another built-in token of the chain reports the same symbol, and adds the token on approval. `AssetsController` gains `isTracked` and `tokenMetadata`; `RequestControllerOptions` takes a required `tokens` and `Eip1193HandlerOptions` a required `isTracked`.
- `solana:signIn` (Sign In With Solana) is registered in the injected Wallet Standard wallet; the message text from `connect/siws.ts` is byte-identical to `@solana/wallet-standard-util` 1.2.0 and bound to the page's host.
- `@qntx/wallet-engine/connect`: Solana `signMessage` now refuses non-UTF-8 bytes with `4200` like `personal_sign`, and a Solana message request's display carries `message.text` (and `signIn`).
- Sessions must be reconnected to use `wallet_watchAsset` and `solana:signIn`: they are new session methods.

- `@qntx/wallet-engine`: transaction simulation for display. Internal EVM and Solana sends, dApp
`evm.transaction` requests and single-transaction `solana-sign` requests carry a
`simulation: SimulationOutcome` (`success` with signed `AssetChange`s, `reverted` or
Expand Down Expand Up @@ -57,20 +67,6 @@ A `vX.Y.Z` tag runs `publish-npm.yml` (publishing `packages/wallet`, `packages/w
from `@qntx/wallet-engine/idb`).
- `@qntx/gateway` (staging): a `scheduled` handler and a `RISK` KV namespace for the list; the build is not scheduled until its hosting is decided.

### Changed

- **Breaking:** `RequestControllerOptions` takes a required `simulateSolana`, and
`@qntx/wallet-chains` `parseCompiledMessage` returns `lookups` (table address with writable and
readonly indexes) in place of `lookupCount`/`lookupAddresses`.
- **Breaking:** `EngineOptions.publicStore` is required, and `ConnectionController` and
`RequestController` take a required `phishing` option.
- `@qntx/wallet-engine`: `engine.unsubscribe()` also stops the phishing list refresh.
- The install-id `fetch` for the gateway moved from `NetworkController` to `gateway/client.ts`.

## [0.8.1] - 2026-11-05

A native wallet can unlock again after it locks, without restarting the app.

### Fixed

- `packages/wallet-native`: after a lock (manual or background auto-lock), a wallet deletion or a
Expand All @@ -83,6 +79,16 @@ A native wallet can unlock again after it locks, without restarting the app.
- `packages/wallet-native`: `NativeWalletOptions.host` is replaced by `createHost`, a factory called
once per kernel runtime. Hosts that passed `host: fake` pass `createHost: () => fake`, creating
a new fake per call when the test must survive a lock.
- `@qntx/wallet-engine/connect`: the injected Solana Wallet Standard wallet now conforms to `@wallet-standard/base` and `@solana/wallet-standard-features` (typed, no cast): every feature is versioned `1.0.0`, `solana:signTransaction` and `solana:signAndSendTransaction` declare `supportedTransactionVersions: ["legacy", 0]` and are variadic (N inputs become one host request, one approval), `signMessage` returns `[{ signedMessage, signature, signatureType }]`, `standard:events` `on` returns an unsubscribe function, and each input's `account` and `chain` are forwarded. The handler rejects an account other than the session's (`4100`), an unknown or mixed chain (`-32602`) and a chain the session is not authorized for (`4100`); sign-and-send needs a chain and returns raw signature bytes.
- `@qntx/wallet-engine/connect`: Solana `signMessage` now refuses non-UTF-8 bytes with `4200` like `personal_sign`, and a Solana message request's display carries `message.text` (and `signIn`).
- Sessions must be reconnected to use `wallet_watchAsset` and `solana:signIn`: they are new session methods.
- **Breaking:** `RequestControllerOptions` takes a required `simulateSolana`, and
`@qntx/wallet-chains` `parseCompiledMessage` returns `lookups` (table address with writable and
readonly indexes) in place of `lookupCount`/`lookupAddresses`.
- **Breaking:** `EngineOptions.publicStore` is required, and `ConnectionController` and
`RequestController` take a required `phishing` option.
- `@qntx/wallet-engine`: `engine.unsubscribe()` also stops the phishing list refresh.
- The install-id `fetch` for the gateway moved from `NetworkController` to `gateway/client.ts`.

## [0.8.0] - 2026-11-04

Expand Down
38 changes: 19 additions & 19 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/wallet-chains/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qntx/wallet-chains",
"version": "0.8.1",
"version": "0.9.0",
"description": "qntx/wallet chain semantics: SignRequest codecs, display decoding, verifiability and signing for EVM, Solana and Bitcoin",
"license": "MIT OR Apache-2.0",
"author": "QuantX <x@qntx.org>",
Expand Down
12 changes: 6 additions & 6 deletions packages/wallet-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qntx/wallet-engine",
"version": "0.8.1",
"version": "0.9.0",
"description": "qntx/wallet engine primitives: controllers, events and encrypted engine storage",
"license": "MIT OR Apache-2.0",
"author": "QuantX <x@qntx.org>",
Expand Down Expand Up @@ -69,9 +69,9 @@
"@qntx/nostr": "0.15.3",
"@qntx/spark": "0.5.2",
"@qntx/spark-wasm": "0.5.2",
"@qntx/wallet": "0.8.1",
"@qntx/wallet-chains": "0.8.1",
"@qntx/wallet-worker": "0.8.1",
"@qntx/wallet": "0.9.0",
"@qntx/wallet-chains": "0.9.0",
"@qntx/wallet-worker": "0.9.0",
"@solana-program/token-2022": "0.20.0",
"@solana/wallet-standard-features": "1.5.0",
"@solana/wallet-standard-util": "1.2.0",
Expand All @@ -85,8 +85,8 @@
"peerDependencies": {
"@qntx/nostr": "~0.15.3",
"@qntx/spark": "~0.5.2",
"@qntx/wallet": "0.8.1",
"@qntx/wallet-chains": "0.8.1"
"@qntx/wallet": "0.9.0",
"@qntx/wallet-chains": "0.9.0"
},
"devEngines": {
"packageManager": {
Expand Down
6 changes: 3 additions & 3 deletions packages/wallet-kernel/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qntx/wallet-kernel",
"version": "0.8.1",
"version": "0.9.0",
"private": true,
"description": "qntx/wallet secret enclave kernel (private, bundled by the host packages)",
"license": "MIT OR Apache-2.0",
Expand All @@ -26,8 +26,8 @@
"@noble/hashes": "2.4.0",
"@qntx/nostr": "0.15.3",
"@qntx/spark": "0.5.2",
"@qntx/wallet": "0.8.1",
"@qntx/wallet-chains": "0.8.1",
"@qntx/wallet": "0.9.0",
"@qntx/wallet-chains": "0.9.0",
"@scure/base": "2.4.0",
"@scure/bip32": "2.4.0",
"@scure/bip39": "2.4.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/wallet-native/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qntx/wallet-native",
"version": "0.8.1",
"version": "0.9.0",
"description": "Native kernel runtime host for the qntx wallet — CBOR transport, KernelHost adapter and createNativeWallet",
"license": "MIT OR Apache-2.0",
"author": "QuantX <x@qntx.org>",
Expand Down Expand Up @@ -60,7 +60,7 @@
"peerDependencies": {
"@qntx/nostr-native": "0.15.3",
"@qntx/spark-native": "0.5.2",
"@qntx/wallet": "0.8.1",
"@qntx/wallet": "0.9.0",
"react-native": "~0.88.0",
"react-native-nitro-modules": "~0.37.1"
}
Expand Down
8 changes: 4 additions & 4 deletions packages/wallet-worker/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qntx/wallet-worker",
"version": "0.8.1",
"version": "0.9.0",
"description": "Web Worker and worker_threads hosts for @qntx/wallet",
"keywords": [
"nostr",
Expand Down Expand Up @@ -67,8 +67,8 @@
"@qntx/spark": "0.5.2",
"@qntx/spark-wasm": "0.5.2",
"@qntx/tsconfig": "1.0.1",
"@qntx/wallet": "0.8.1",
"@qntx/wallet-kernel": "0.8.1",
"@qntx/wallet": "0.9.0",
"@qntx/wallet-kernel": "0.9.0",
"@scure/base": "2.4.0",
"@scure/btc-signer": "2.4.1",
"@types/node": "26.6.5",
Expand All @@ -77,7 +77,7 @@
"vite-plus": "1.4.0"
},
"peerDependencies": {
"@qntx/wallet": "0.8.1"
"@qntx/wallet": "0.9.0"
},
"devEngines": {
"packageManager": {
Expand Down
6 changes: 3 additions & 3 deletions packages/wallet/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qntx/wallet",
"version": "0.8.1",
"version": "0.9.0",
"description": "Self-custodial wallet SDK: Wallet host entry, protocol and types",
"keywords": [
"sdk",
Expand Down Expand Up @@ -84,7 +84,7 @@
"@qntx/nostr": "0.15.3",
"@qntx/spark": "0.5.2",
"@qntx/tsconfig": "1.0.1",
"@qntx/wallet-chains": "0.8.1",
"@qntx/wallet-chains": "0.9.0",
"@scure/bip32": "2.4.0",
"@scure/bip39": "2.4.0",
"@scure/btc-signer": "2.4.1",
Expand All @@ -96,7 +96,7 @@
"peerDependencies": {
"@qntx/nostr": "~0.15.3",
"@qntx/spark": "~0.5.2",
"@qntx/wallet-chains": "0.8.1"
"@qntx/wallet-chains": "0.9.0"
},
"peerDependenciesMeta": {
"@qntx/nostr": {
Expand Down
Loading