DocsWallets
Wallets

Wallet integration

Generate Level 20 parent identities, derive ephemeral children, sign transactions, and handle recovery from code.

Intermediate12 min read
Mental model

One identity, many spends

A QuanChain wallet is a pair: a permanent Level 20 parent identity and an ever-extending Merkle tree of child wallets. The user only ever holds the parent seed phrase. Children are derived deterministically from a chain code held inside the wallet's local keystore and authenticated on-chain via the parent registration.

Parent seed

24-word BIP-39 phrase. Derives the composite Level 20 key + chain code.

Chain code

BLAKE3-derived secret. Combines with index N to produce child N.

Active child

The currently funded wallet. Rotated on every successful spend.

Step 1

Create a wallet

The SDK exposes wallet.create() which generates a fresh parent identity. The returned object includes the seed phrase — it must be persisted by the caller (the SDK does not store it).

typescript
import { QuanChain } from '@quanchain/sdk';

const chain = new QuanChain({ network: 'testnet' });
const wallet = await chain.wallet.create({ level: 20 });

console.log('Seed phrase:', wallet.seedPhrase);   // 24 words
console.log('Parent addr:', wallet.parentAddress); // QC20_...
console.log('Chain code: ', wallet.chainCode);    // hex
Seed handling
The seed phrase reconstructs the composite Level 20 key. Treat it like a hardware-wallet seed: store offline, never paste into a browser console in production, never log it.
Step 2

Derive a child wallet

Child wallets are derived at sign-time and registered as part of the SpendAndRotate envelope. Manual derivation is exposed for advanced integrations such as cold-signing.

typescript
const child = await wallet.deriveChild({
  index: 0,         // next unused index
  level: 10,        // hybrid Dilithium2 + ECDSA-P256
});

console.log('Child address:', child.address);     // QC10_...
console.log('Merkle proof: ', child.merkleProof); // base58, ~640 bytes

Derivation is deterministic and offline — no network call is required. The proof embedded in the resulting transaction lets validators verify parentage in constant time.

Step 3

Sign and broadcast a transaction

The high-level helper handles derivation, signing, and rotation in one call.

typescript
const receipt = await wallet.transfer({
  to:      'QC10_2k9...f81a',
  amount:  '12.50',
  channel: 1,
});

receipt.txHash             // hash on Channel 1
receipt.newChildAddress    // freshly rotated active wallet
receipt.merkleProofBytes   // size of the inline proof
receipt.finalityMs         // ~200ms on Channel 1

For lower-level control, wallet.signTx(tx) returns the signed envelope without broadcasting. Useful for offline signing flows.

Verification

Merkle proofs in detail

Each child carries a proof tying its public key to the parent's registered Merkle root. The proof shape:

typescript
interface MerkleProof {
  childIndex: number;       // 0-based index in the parent tree
  siblings: Uint8Array[];   // 20 sibling hashes (depth 20)
  parentRoot: Uint8Array;   // 32-byte root (on-chain at registration)
}

Validators recompute the root from the child's public key and the sibling path. If the recomputed root matches the on-chain commitment, the spend is authentic. A standard proof verifies in under 50 microseconds.

Failsafe

Recovery flow

A composite parent signature can re-anchor the wallet to a brand new Merkle root, retiring every child generated up to that point. Use cases: leak suspicion, hygiene rotation, or migration to a higher security level.

typescript
await wallet.recover({
  reason: 'leak_suspected',
  newLevel: 12,           // optional — escalate to SPHINCS+
});
Recovery cost
A recovery transaction broadcasts the full 34.4 KB composite signature on Channel 2. The chain fee is correspondingly larger. Most wallets will never need this.
Reference

Address formats

Addresses encode the security level directly in the prefix. Examples:

text
QC1_3Hf2...      Level 1 (classical, ECDSA-secp256k1)
QC10_2k9...      Level 10 (hybrid, Dilithium3 + Ed25519)
QC15_8mp...      Level 15 (post-quantum, SPHINCS+-SHA2-256f + Dilithium5)
QC20_qNa...      Level 20 (composite parent identity)

The body is a base58-encoded truncation of a BLAKE3 hash whose length scales with the level. Higher levels produce longer addresses (resistant to Grover preimage searches).

Build with

Wallet integrations

Browser extension

window.quanchain provider. Web3-style request() interface plus native qc_spendAndRotate.

Mobile SDK

iOS (Swift) + Android (Kotlin) bindings backed by the Rust core. Same key model as desktop.

Hardware

Ledger / Trezor apps in beta. Composite signing is delegated to the host machine for performance.

Server-side

@quanchain/sdk runs in Node.js and Bun. Suitable for custody backends and validator tooling.

Wallet catalogue + downloads: /resources/wallets.

Want help?

Join the developer Discord, open a GitHub issue, or read the whitepaper.