Kaspa Forge is a non-custodial platform built on Kaspa's Toccata covenant layer. Its product family — Safe vaults, Escrow for P2P deals, Deposit collateral, a Marketplace, public Boards, Arena Blackjack, and the Desk wallet — share a single architectural spine: an encrypted browser profile that holds your keys, a Rust-to-WASM cryptographic core that signs every transaction locally, on-chain covenant contracts that enforce money rules at the protocol level, and a server layer that indexes state without ever touching private keys. This article traces each layer, maps the trust boundary between them, and honestly flags the current product limits.
The Problem: Custodial Risk Meets Scattered Tooling
Custodial platforms hold your keys. If the operator disappears or is compromised, funds follow. Multi-product crypto ecosystems compound the risk: each tool may introduce its own key storage, its own server trust assumptions, and its own recovery story. The user ends up managing *N* separate seeds or trusting *N* separate operators. Kaspa Forge answers this by building every product on the same non-custodial spine — one encrypted profile, one cryptographic core, one family of on-chain contracts — so adding a new tool does not add a new custodian.
Five Layers, One Architecture
The platform breaks into five layers, each with a distinct role and a clear boundary to the next:
1. Browser-held keys — the Desk encrypted profile and HD master seed 2. WASM cryptographic core — kaspa-safe-core, one Rust crate compiled to browser and server targets 3. Covenant money — Toccata contracts enforced on-chain by the Kaspa node 4. Server and indexer — API, profile mirror, notifications, transaction relay 5. Kaspa node — BlockDAG consensus, UTXO state, covenant script execution
Covenant (Toccata context): An on-chain spending policy compiled from SilverScript into Kaspa's Toccata opcodes. A covenant UTXO can only be spent if the transaction satisfies the script's conditions — time locks, key checks, output state validation — regardless of who holds the signing keys.
The rest of this article walks through each layer in detail.
Layer 1 — Browser-Held Keys: The Desk Profile
Every Kaspa Forge product starts from the same encrypted profile, managed by Desk. The current profile format (version 3) holds:
- An HD master seed from which all keys are derived. The derivation path follows the pattern
kaspaforge/v1/vault/<index>, so one seed covers every vault, escrow deal, and Arena game identity a user creates — including future ones not yet generated. - Per-product secret keys:
hot_skfor owner withdrawal,alarm_sk(or a flag indicating the alarm key lives on a physical card outside the profile), andfunding_skfor deposit operations. - Wallet addresses — a current receive address (
wallet) and previous addresses (walletOld). Balance is the sum of UTXO across all of them. Each input is signed by its own key; change returns to the current address. - A
.agekey-file — the only portable copy of the entire profile, encrypted with theageencryption tool using a scrypt passphrase, ASCII-armored, and compatible with the upstreamage -dCLI.
master seed
│
├─ kaspaforge/v1/vault/0 → vault #0 keys
├─ kaspaforge/v1/vault/1 → vault #1 keys
├─ kaspaforge/v1/vault/2 → escrow keys
└─ ...
Session security is enforced per page. A boot-guard (requireUnlock) demands the password before any product surface loads. Withdrawals and signing operations trigger a second password prompt that displays the exact amount and recipient. The session auto-locks after 15 minutes of inactivity.
The critical property: private keys and the master seed exist only in the browser's memory and in the encrypted .age backup. The server receives public keys, vault parameters, and already-signed transactions — never the secrets themselves.
Layer 2 — One Rust Crate, Two Targets
All cryptographic operations — key generation, HD derivation, transaction building, covenant compilation, .age encryption, and chat encryption — live in a single Rust crate called kaspa-safe-core. It compiles to two targets:
cdylibviawasm-pack build --target web→ a browser WASM bundle loaded by every product page.rlib→ linked into the server binary for operations that require the same logic server-side (transaction validation, profile sync).
The crate depends on silverscript-lang (the covenant compiler), rusty-kaspa crates pinned to tag v2.0.1, secp256k1, an ECIES encryption stack for chat, and the age library for profile encryption.
Because the same Rust source produces both targets, key derivation and transaction building are byte-for-byte identical in browser and server. This eliminates a class of bugs where client and server disagree on address format, fee calculation, or covenant structure.
Production Desk currently loads WASM generation v9, which adds exact fixed-point fee calculation for wallet sends — the browser reads the node's current fee rate, builds the signed transaction in WASM, and computes the normalized fee to the sompi without an artificial floor. Older product surfaces — the vanilla Safe pages (v3) and Escrow/Deposit pages (v5) — pin their own immutable snapshots from the same crate. Each generation is a frozen build; a new export gets its own directory and import path to prevent browser-cache collisions where one page loads a function that another page's bundle does not export.
Layer 3 — Covenant Money on the BlockDAG
Toccata: Kaspa's mainnet covenant activation. It introduces opcodes that let on-chain scripts inspect transaction structure — inputs, outputs, amounts, sequence locks — enabling spending policies beyond simple signature checks.
The money itself lives in Toccata covenant UTXOs on the Kaspa BlockDAG. The Kaspa wiki documents how the GHOSTDAG consensus orders blocks and transactions; covenant scripts are executed by the node's script engine as part of normal transaction validation.
Each product has its own contract compiled from SilverScript:
vault.sil— the Safe vault with multiple spending paths: owner withdrawal (after a user-chosen delay), alarm cancel (a separate key can reverse a theft attempt before the timer expires), inherit check-in, and inherit auto-complete. The delay, alarm key, and inheritance conditions are set at vault creation and cannot be changed without migrating to a new on-chain UTXO.escrow.sil— the Escrow contract for P2P deals, with release, dispute, auto-release, and timeout paths. The Deposit contract uses the same escrow core with a different template for collateral scenarios.- Arena Room/Game covenants — Arena Blackjack funds lock in Room bond and Game UTXOs with their own spending paths for joining, playing, and settling.
These contracts enforce spending rules regardless of who builds the transaction. A vault UTXO cannot be spent outside its defined paths even if an attacker has the full server-side source code. This is the layer that makes the platform non-custodial at the protocol level: the money obeys the contract, not the operator.
Layers 4 & 5 — Server, Indexer, and Node
Server: An API backend handles indexing (balances, UTXO status, escrow state), a Profile Mirror service for cross-device encrypted profile sync (the server stores encrypted blobs it cannot read), push notifications (event-based, privacy-minimal payloads), and transaction relay (submitting already-signed transactions to the node). The server connects to a Kaspa node for UTXO queries and block state. It does not hold keys, does not sign transactions, and does not construct spending transactions.
Node: A Kaspa node running GHOSTDAG consensus provides ground truth — current UTXO set, block acceptance, transaction validation, and covenant script execution. Kaspa Forge exposes a public node endpoint for recovery scenarios, but the open-source vaultctl CLI can connect to any Kaspa v2+ node, not just the Kaspa Forge one.
┌──────────────────────────────────────┐
│ BROWSER (your device) │
│ Private keys · HD seed · Signing │
│ WASM core · Profile encryption │
└───────────┬──────────────────────────┘
│ signed transactions + public data
┌───────────▼──────────────────────────┐
│ SERVER (Kaspa Forge) │
│ Indexing · API · Mirror · Relay │
│ No keys · No signing · No spending │
└───────────┬──────────────────────────┘
│ broadcast + queries
┌───────────▼──────────────────────────┐
│ NODE + BLOCKDAG (Kaspa network) │
│ Consensus · UTXO · Covenant exec │
└──────────────────────────────────────┘
If the server disappears, the browser profile and the on-chain contracts remain intact. Recovery tools — keyfile-decrypt.html (a standalone single-file WASM decryptor that works offline at file:// with zero network requests) and vaultctl (an open-source CLI) — reconstruct any vault against any node without needing the Kaspa Forge backend.
How Each Product Routes Through the Stack
Every Kaspa Forge product enters through the same Desk profile and WASM core but routes to a different covenant contract and server endpoint:
- Kaspa Safe — Desk derives vault keys from the HD seed, the WASM core builds the covenant funding transaction, and the vault UTXO goes on-chain. Withdrawal, alarm, and inheritance all follow paths defined in
vault.sil. The watcher service monitors timers and triggers automatic completion when conditions are met. - Kaspa Escrow — two parties open a deal; funds lock in an escrow covenant UTXO. Release, dispute, and timeout follow
escrow.silpaths. Chat between parties is end-to-end encrypted using the ECIES protocol from the WASM core. - Deposit — collateral locks in a deposit covenant with return, claim, and dispute paths. Same escrow core, different contract template. Designed for rental deposits, work escrow, and access gating.
- Marketplace — listings are server-indexed; each sale routes into a separate escrow deal. The marketplace never holds buyer funds.
- Boards — signed posts, replies, images, and KAS tips go on-chain. The server indexes them for display but cannot alter content. Moderation operates on the read layer, not on the BlockDAG.
- Arena Blackjack (public mainnet beta) — Room and Game covenant UTXOs hold player and dealer funds. The Desk signer builds and signs every transaction locally; the Arena controller coordinates game flow but never touches keys. ZK proofs verify the hidden deck and shuffle; commitments and Merkle openings handle randomness and reveals. Room and Game covenants are separate monetary boundaries from the vault and escrow contracts.
- Desk — the shared entry point. One encrypted profile, one HD seed, one session lock. Overview, Wallet, Safes, Escrow, Deposits, Boards, Market, and Arena all load from the same surface.
Start from one profile. Desk gives you a single encrypted keyring for every Kaspa Forge tool — vaults, escrow, deposits, marketplace deals, and Arena games. Keys stay in your browser; the .age backup works even if the service is down. Explore Desk or read the full platform architecture docs.
Trade-offs and Honest Boundaries
No architecture comes free. Here are the real trade-offs:
- Browser-only keys mean browser-only risk. If the browser is compromised by malware or an XSS vulnerability, keys can be exfiltrated. Kaspa Forge minimizes JavaScript surface and runs a Content Security Policy (currently in report-only mode), but the threat model ultimately depends on the user's device security.
- The HD seed is a single point of failure. One master seed derives every key. If the
.agebackup and the password are both lost, recovery is impossible. If the seed leaks, every vault, escrow, and Arena identity is compromised. This is the standard trade-off of hierarchical deterministic wallets. - Covenants are immutable once funded. A vault UTXO follows the paths compiled into its script. Changing parameters means creating a new vault and migrating funds — an on-chain transaction with a new address. The
vaultctlCLI supports this migration, but the platform cannot silently upgrade live funds. - Product status is a hard boundary. Arena Blackjack is a public mainnet beta — the covenant scripts have passed extensive testing (300+ case matrices, funded consensus-transaction verification on pinned Toccata), but the product surface, ZK proving infrastructure, and game coordination are still being hardened. Dice remains engineering work with its permanent production arm off pending independent review. Duel and baccarat are roadmap ideas, not products. Tokens is a planned permissionless launcher; it is not live on mainnet.
- Recovery depends on node availability.
vaultctlworks against any Kaspa v2+ node, so you are not locked to Kaspa Forge infrastructure — but you do need a synced node somewhere. The public node endpoint and the standalonekeyfile-decrypt.htmltool reduce this dependency but do not eliminate it. - Profile sync stores encrypted blobs. The Forge Mirror service syncs your encrypted
.ageprofile across devices. The server cannot read the contents, but it does store the ciphertext. Users who prefer zero server-side storage can rely solely on local.agebackups and skip the mirror.
The non-custodial guarantee is real, but it is not magic. It shifts responsibility from the platform to the user's operational security — password strength, backup discipline, and device hygiene. Kaspa Forge provides the tools (Desk, vaultctl, keyfile-decrypt.html); the user provides the care.
FAQ
Where are my private keys stored?
Only in your browser's memory while Desk is unlocked and in your encrypted .age backup file. The Kaspa Forge server never receives, stores, or has access to private keys or your HD seed.
Can I recover my funds if Kaspa Forge goes offline?
Yes. The open-source vaultctl CLI reconstructs any vault against any Kaspa v2+ node. The standalone keyfile-decrypt.html tool decrypts your .age profile entirely offline, with no network requests.
Why do different pages load different WASM versions?
Each product surface pins an immutable snapshot of the shared Rust cryptographic core. Safe pages load v3, Escrow/Deposit load v5, and production Desk loads v9. All are built from the same source crate; separate snapshots prevent browser-cache collisions between surfaces.
Are the Kaspa Forge contracts open source?
Yes. Vault, escrow, and marketplace contracts are published along with the recovery toolkit, vaultctl CLI, and a 25-check self-test that runs against the node's VM.
What does non-custodial mean for Arena Blackjack?
Arena funds live in on-chain Room/Game covenant UTXOs. Your Desk signer builds and signs every transaction locally; the Arena controller coordinates game flow but never holds keys or submits unsigned transactions.
Is the Kaspa Forge Tokens feature live?
No. Tokens is a planned permissionless launcher with an approved design specification. It is not live on mainnet today.
Put your KAS where theft can be cancelled
A covenant vault on Kaspa mainnet: your keys, your rules, our tooling. Free on-chain, forever.
Create a vault
