Quantum-resistant wallet library for The QRL using ML-DSA-87 (FIPS 204)
npm install @theqrl/wallet.js
!test

Quantum-resistant wallet library for The QRL using ML-DSA-87 (FIPS 204).
- ML-DSA-87 digital signatures (NIST post-quantum standard)
- Deterministic key derivation from seeds
- Mnemonic phrase backup (34 words)
- Address generation and validation
- Works in Node.js and browsers
- Dual ESM/CommonJS support
``bash`
npm install @theqrl/wallet.js
`javascript
import { MLDSA87, Seed, isValidAddress } from '@theqrl/wallet.js';
// Create a new random wallet
const wallet = MLDSA87.newWallet();
console.log('Address:', wallet.getAddressStr());
console.log('Mnemonic:', wallet.getMnemonic());
// Sign a message
const message = new TextEncoder().encode('Hello QRL!');
const signature = wallet.sign(message);
// Verify signature
const isValid = MLDSA87.verify(signature, message, wallet.getPK());
console.log('Valid:', isValid); // true
// Clean up sensitive data
wallet.zeroize();
`
`javascript
const { MLDSA87, Seed, isValidAddress } = require('@theqrl/wallet.js');
const wallet = MLDSA87.newWallet();
console.log('Address:', wallet.getAddressStr());
`
#### MLDSA87.newWallet([metadata])
Creates a new wallet with a random seed.
`javascript`
const wallet = MLDSA87.newWallet();
const walletWithMeta = MLDSA87.newWallet([0x01, 0x02]); // Custom 2-byte metadata
#### MLDSA87.newWalletFromSeed(seed, [metadata])
Creates a wallet from an existing seed (deterministic).
`javascript`
const seed = Seed.from('0x' + '00'.repeat(48)); // 48-byte hex string
const wallet = MLDSA87.newWalletFromSeed(seed);
#### MLDSA87.newWalletFromMnemonic(mnemonic)
Restores a wallet from a mnemonic phrase.
`javascript`
const mnemonic = 'absorb aback veto waiter rail aroma...'; // 34 words
const wallet = MLDSA87.newWalletFromMnemonic(mnemonic);
#### newWalletFromExtendedSeed(extendedSeed)
Factory function that auto-detects wallet type from extended seed.
`javascript
import { newWalletFromExtendedSeed } from '@theqrl/wallet.js';
const wallet = newWalletFromExtendedSeed('0x01000000...'); // 51-byte hex
`
| Method | Returns | Description |
|--------|---------|-------------|
| getAddressStr() | string | Address with Q prefix (e.g., Qabc123...) |getAddress()
| | Uint8Array | Raw 20-byte address |getMnemonic()
| | string | 34-word mnemonic phrase |getPK()
| | Uint8Array | Public key (2,592 bytes) |getSK()
| | Uint8Array | Secret key (4,896 bytes) |getHexExtendedSeed()
| | string | Extended seed as hex with 0x prefix |sign(message)
| | Uint8Array | Sign a message (4,627-byte signature) |zeroize()
| | void | Overwrite sensitive data with zeros |
| Method | Description |
|--------|-------------|
| MLDSA87.verify(signature, message, pk) | Verify a signature, returns boolean |
Address Format: Q prefix + 40 lowercase hex characters (41 chars total).
- Output is always lowercase; input parsing is case-insensitive
- No checksum encoding (unlike EIP-55)
`javascript
import {
addressToString,
stringToAddress,
isValidAddress
} from '@theqrl/wallet.js';
// Convert bytes to string
const addrStr = addressToString(addressBytes); // 'Qabc...'
// Convert string to bytes (case-insensitive)
const addrBytes = stringToAddress('Qabc123...');
const same = stringToAddress('QABC123...'); // Also valid
// Validate address format
if (isValidAddress(userInput)) {
// Safe to use
}
`
`javascript
import {
Seed,
ExtendedSeed,
Descriptor,
newMLDSA87Descriptor,
SEED_SIZE, // 48
EXTENDED_SEED_SIZE, // 51
DESCRIPTOR_SIZE // 3
} from '@theqrl/wallet.js';
// Create seed from hex
const seed = Seed.from('0x' + 'ab'.repeat(48));
// Create descriptor
const descriptor = newMLDSA87Descriptor([0x00, 0x00]);
// Create extended seed
const extSeed = ExtendedSeed.newExtendedSeed(descriptor, seed);
`
See SECURITY.md for the security model and best practices.
Important:
- Always call wallet.zeroize() when doneisValidAddress()
- Never log or transmit mnemonics/seeds
- Validate addresses with before use
The library works in browsers via bundlers (webpack, vite, etc.):
`javascript
import { MLDSA87 } from '@theqrl/wallet.js';
const wallet = MLDSA87.newWallet();
`
Uses Web Crypto API for secure random number generation.
This library currently supports ML-DSA-87 (FIPS 204), the NIST standardized version of Dilithium.
| Property | Value |
|----------|-------|
| Security Level | NIST Level 5 |
| Public Key | 2,592 bytes |
| Secret Key | 4,896 bytes |
| Signature | 4,627 bytes |
- @theqrl/mldsa87 - ML-DSA-87 implementation@noble/hashes
- - SHA-256, SHAKE-256randombytes` - Secure random generation
-