A user can create a wallet from a fresh BIP39 mnemonic, restore one from a phrase or a quantus-cli wallet file, and sign with it, with the secret material never leaving Rust and never touching disk unencrypted. The keystore file format is quantus-cli's (Argon2id + AES-256-GCM, EncryptedWallet), so a wallet moves freely between this app, the CLI and the browser extension.
Facts the design rests on
Quantus signs with ML-DSA. The chain's Signature is DilithiumSignatureScheme { Dilithium87, Dilithium65 } and carries the public key on the wire because the account id is Poseidon2 of the public key.
Derivation is qp-rusty-crystals-hdwallet at m/44'/189189'/account'/change'/index', every level hardened. The other Quantus wallets use index 0' for ML-DSA-87 and 1' for ML-DSA-65; new accounts default to 65.
Extrinsics are signed under the FIPS 204 context QUANTUS_EXTRINSIC from spec 148; mainnet is at 152. The context is a property of the chain profile, not of the key.
The CLI keystore already zeroizes, redacts Debug, and verifies the decrypted key against the stored address before use. Match all three.
Operator-owned decisions
OS keychain integration (Secret Service, Keychain, Credential Manager) for the unlock secret, or password-only with an auto-lock timer. Default: password-only first; keychain is a follow-up child, not a blocker.
Definition of done
A mnemonic created here restores in quantus-cli 2.x to the same qz… address and checkphrase, and a wallet file exported by quantus-cli opens here. A signature produced here over a Quantus signing payload verifies on a dev node. No test, log line or Debug output can print a seed, mnemonic or secret key.
## Goal
A user can create a wallet from a fresh BIP39 mnemonic, restore one from a phrase or a quantus-cli wallet file, and sign with it, with the secret material never leaving Rust and never touching disk unencrypted. The keystore file format is quantus-cli's (Argon2id + AES-256-GCM, `EncryptedWallet`), so a wallet moves freely between this app, the CLI and the browser extension.
## Facts the design rests on
- Quantus signs with ML-DSA. The chain's `Signature` is `DilithiumSignatureScheme { Dilithium87, Dilithium65 }` and carries the public key on the wire because the account id is Poseidon2 of the public key.
- Derivation is `qp-rusty-crystals-hdwallet` at `m/44'/189189'/account'/change'/index'`, every level hardened. The other Quantus wallets use index `0'` for ML-DSA-87 and `1'` for ML-DSA-65; new accounts default to 65.
- Extrinsics are signed under the FIPS 204 context `QUANTUS_EXTRINSIC` from spec 148; mainnet is at 152. The context is a property of the chain profile, not of the key.
- The CLI keystore already zeroizes, redacts `Debug`, and verifies the decrypted key against the stored address before use. Match all three.
## Operator-owned decisions
- OS keychain integration (Secret Service, Keychain, Credential Manager) for the unlock secret, or password-only with an auto-lock timer. **Default: password-only first; keychain is a follow-up child, not a blocker.**
## Definition of done
A mnemonic created here restores in quantus-cli 2.x to the same `qz…` address and checkphrase, and a wallet file exported by quantus-cli opens here. A signature produced here over a Quantus signing payload verifies on a dev node. No test, log line or `Debug` output can print a seed, mnemonic or secret key.
Children, in dependency order: #14 (ML-DSA key schemes) → #15 (quantus-cli keystore) and #16 (mnemonic lifecycle) → #17 (unlock session). OS keychain is a follow-up to #17, filed when #17 lands.
Children, in dependency order: #14 (ML-DSA key schemes) → #15 (quantus-cli keystore) and #16 (mnemonic lifecycle) → #17 (unlock session). OS keychain is a follow-up to #17, filed when #17 lands.
Done. #14 through #17 are closed by commits on main. Against the definition of done:
A mnemonic derived here matches quantus-cli 2.2.2 for both schemes at three paths each (six vectors), and the checkphrase for the dev phrase's ML-DSA-65 account matches quantus wallet view (Indicate-Dew-Undamaged-Axis-Obtain).
Eight real CLI wallet files plus the two dev-chain accounts open here; a wallet written here lists in quantus wallet list with the expected address.
A signature produced here verifies on a node: Planck's public node refused an unfunded transfer for payment, not signature, and refused the same transfer signed under the empty context as a bad signature; the dev node then accepted real transfers (#22).
No test, log or Debug prints a secret: every holder redacts, and a Linux test scans the process's writable memory after lock() for a runtime-built seed and secret and finds neither, in debug and release.
Deferred as its own follow-up when wanted: the OS keychain for the unlock secret. Password-only with a ten-minute idle lock is what ships.
Done. #14 through #17 are closed by commits on `main`. Against the definition of done:
- A mnemonic derived here matches quantus-cli 2.2.2 for both schemes at three paths each (six vectors), and the checkphrase for the dev phrase's ML-DSA-65 account matches `quantus wallet view` (`Indicate-Dew-Undamaged-Axis-Obtain`).
- Eight real CLI wallet files plus the two dev-chain accounts open here; a wallet written here lists in `quantus wallet list` with the expected address.
- A signature produced here verifies on a node: Planck's public node refused an unfunded transfer for *payment*, not signature, and refused the same transfer signed under the empty context as a bad signature; the dev node then accepted real transfers (#22).
- No test, log or `Debug` prints a secret: every holder redacts, and a Linux test scans the process's writable memory after `lock()` for a runtime-built seed and secret and finds neither, in debug and release.
Deferred as its own follow-up when wanted: the OS keychain for the unlock secret. Password-only with a ten-minute idle lock is what ships.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
A user can create a wallet from a fresh BIP39 mnemonic, restore one from a phrase or a quantus-cli wallet file, and sign with it, with the secret material never leaving Rust and never touching disk unencrypted. The keystore file format is quantus-cli's (Argon2id + AES-256-GCM,
EncryptedWallet), so a wallet moves freely between this app, the CLI and the browser extension.Facts the design rests on
SignatureisDilithiumSignatureScheme { Dilithium87, Dilithium65 }and carries the public key on the wire because the account id is Poseidon2 of the public key.qp-rusty-crystals-hdwalletatm/44'/189189'/account'/change'/index', every level hardened. The other Quantus wallets use index0'for ML-DSA-87 and1'for ML-DSA-65; new accounts default to 65.QUANTUS_EXTRINSICfrom spec 148; mainnet is at 152. The context is a property of the chain profile, not of the key.Debug, and verifies the decrypted key against the stored address before use. Match all three.Operator-owned decisions
Definition of done
A mnemonic created here restores in quantus-cli 2.x to the same
qz…address and checkphrase, and a wallet file exported by quantus-cli opens here. A signature produced here over a Quantus signing payload verifies on a dev node. No test, log line orDebugoutput can print a seed, mnemonic or secret key.Children, in dependency order: #14 (ML-DSA key schemes) → #15 (quantus-cli keystore) and #16 (mnemonic lifecycle) → #17 (unlock session). OS keychain is a follow-up to #17, filed when #17 lands.
Done. #14 through #17 are closed by commits on
main. Against the definition of done:quantus wallet view(Indicate-Dew-Undamaged-Axis-Obtain).quantus wallet listwith the expected address.Debugprints a secret: every holder redacts, and a Linux test scans the process's writable memory afterlock()for a runtime-built seed and secret and finds neither, in debug and release.Deferred as its own follow-up when wanted: the OS keychain for the unlock secret. Password-only with a ten-minute idle lock is what ships.