Self-Custody · Browser-Generated

QSDM Wallet

Generate a quantum-secure (ML-DSA-87, NIST FIPS 204) wallet entirely inside this browser tab. The private key is created locally, encrypted with AES-256-GCM under a passphrase you choose, and offered as a downloadable JSON keystore. Nothing about the keypair touches the QSDM validators, this site's web server, or any third party. Compatible byte-for-byte with qsdmcli wallet.

Read this before clicking anything

1) The QSDM wallet is the only thing standing between you and your coins. If you lose the JSON keystore file or forget the passphrase, the address is permanently unrecoverable — no support team, no reset email, no validator override. Back up the file. Pick a passphrase you will not forget.

2) Verify you are on qsdm.tech (look at the address bar) before generating. A phishing clone of this page could replace the WASM binary and exfiltrate the private key the moment it's generated. Even with HTTPS, treat the wallet page like a hardware-wallet recovery screen.

3) The same keystore format is produced by the offline CLI: qsdmcli wallet new. If you'd rather not trust a webpage, use the CLI on a machine you control — the keystore opens here either way.

Generate a fresh wallet

Choose a strong passphrase (12+ characters, mix of types). The wallet page never sees the passphrase in network traffic: it is fed to PBKDF2-HMAC-SHA-256 (600 000 iterations) inside this browser tab, the derived key encrypts the private key under AES-256-GCM, and the resulting JSON keystore is yours to download.

Waiting for WASM module…

Open an existing keystore

Drop in a wallet.json file (produced here, or by qsdmcli wallet new). The browser will decrypt it locally to confirm the passphrase is correct and the file isn't tampered with. Nothing is uploaded.

Sign a message

Decrypt the keystore and produce a ML-DSA-87 signature over an arbitrary message. The decrypted private key is held only inside the WASM call; the browser zeros the JS reference as soon as the signature is returned.

Check an address balance

Unlike the other three tabs, this one talks to the network. It sends a single GET https://api.qsdm.tech/api/v1/wallet/balance?address=<addr> and renders the response. An address is public information — it's already on chain — so the request leaks no private material, but it does correlate this browser with this address at the validator's HTTP log layer. If you want to avoid that correlation, ask a friend's node, run your own validator, or skip this tab entirely.

Address goes in → balance comes back.

How this works

Or do it from the CLI

Identical keystore format, but offline. Useful for cold-storage flows where you don't want even a static webpage in the trust chain. The mining step uses qsdmminer-console --protocol=v2 against the live NVIDIA-locked mainnet; the legacy CPU qsdmminer binary is no longer a public release artefact (mainnet rejects its v1 proofs at consensus — see MINER_QUICKSTART).

# Build once
git clone https://github.com/blackbeardONE/QSDM
cd QSDM/QSDM/source
go build -o qsdmcli         ./cmd/qsdmcli
go build -o qsdmminer-console ./cmd/qsdmminer-console

# Wallet: generate (passphrase prompted, address printed to stdout)
./qsdmcli wallet new --out ~/.qsdm/wallet.json
ADDR=$(./qsdmcli wallet show | awk '/^address/{print $2}')

# Mining (v2): generate the HMAC key, enroll on-chain (10 CELL bond),
# then start the live miner against the mainnet validator.
./qsdmminer-console --gen-hmac-key=$HOME/.qsdm/hmac.key
./qsdmcli enroll --sender=$ADDR \
            --node-id=rig-77 \
            --gpu-uuid=$(nvidia-smi --query-gpu=uuid --format=csv,noheader | head -1) \
            --hmac-key=$(cat $HOME/.qsdm/hmac.key) \
            --nonce=<your-account-nonce>
./qsdmminer-console --protocol=v2 \
            --validator=https://api.qsdm.tech \
            --address=$ADDR \
            --hmac-key-path=$HOME/.qsdm/hmac.key \
            --node-id=rig-77 \
            --gpu-uuid=$(nvidia-smi --query-gpu=uuid --format=csv,noheader | head -1) \
            --gpu-arch=ada