Self-custody solves one problem and creates another. When you hold your own keys, no exchange can freeze your funds — but no one can hand them to your family if something happens to you, either. A 2024 survey by the Cremation Institute found that roughly 72 % of crypto holders have no plan for transferring digital assets after death. Traditional estate planning for crypto means trusting a custodian, handing a seed phrase to a lawyer, or cobbling together a multisig with family members who may not understand what they're signing.
Kaspa Safe takes a different approach: an on-chain dead-man switch built into a covenant vault on Kaspa's Toccata mainnet. The owner periodically "checks in" with a cryptographic signature. If the checkins stop for longer than a configurable timeout, the vault releases funds to a pre-designated heir — automatically or on the heir's signature, depending on the owner's preference. No third party holds keys. No court order is needed. The mechanism lives in a Kaspa covenant — a script enforced by every validating node on the network.
This article explains how the mechanism works at the protocol level, how the off-chain watcher assists, and where the current design has honest limits.
The Problem: What Happens to Self-Custodied KAS When You're Gone?
A seed phrase stored in a safe deposit box is only as accessible as the person who knows the combination. A hardware wallet in a drawer is inert without the PIN. Even a well-documented multisig requires co-signers to be alive, willing, and technically able to act.
The design space for crypto inheritance has a few known shapes:
- Custodial trust. Exchanges or specialized services hold keys and release funds on proof of death. You're trusting the custodian's solvency, honesty, and legal compliance.
- Social recovery multisig. M-of-N signatures from family or friends. Works if signers understand key management and remain reachable. Fails if relationships change or signers lose their own keys.
- Time-locked contracts. Funds unlock after a deadline, extended by periodic owner actions. This is the dead-man switch pattern — and it's what Kaspa Safe uses.
The dead-man switch is attractive because it requires no external trust: the blockchain itself enforces the timer. But implementing one on a proof-of-work chain with 10 blocks per second requires care around time measurement, UTXO lifecycle, and griefing resistance.
The Building Blocks: Vault State, DAA Score, and Age
Kaspa Safe's vault is a covenant contract written in Silverscript (vault.sil), compiled to Kaspa's script and locked behind a P2SH address. The contract holds a small piece of persistent state:
mode : 0 = VAULT (normal), 1 = UNVAULTING (withdrawal in progress)
dest : 36-byte version-prefixed scriptPubKey (destination for withdrawals)
The vault accepts nine parameters at creation: hot (owner's spending key), alarm (theft-cancel key), delay (withdrawal wait in DAA-score units), heir (inheritance recipient pubkey), inheritDelay (checkin timeout in DAA-score units), autoInherit (0 or 1), feeBudget (network-fee cap, max 0.1 KAS), and initial mode/dest.
The crucial timing primitive is DAA score — the cumulative count of blue blocks plus successfully merged red blocks since genesis. Unlike wall-clock time, DAA score is deterministic and consensus-agreed: every node sees the same value for any given block. When a vault UTXO is spent, the covenant computes the difference between the current virtual DAA score and the DAA score of the block that created the UTXO. This difference is the UTXO's age. When the contract checks require(age >= delay), it's asking: "has this UTXO existed for at least delay DAA-score units without being spent?"
DAA score — Kaspa's consensus-level timestamp: the cumulative count of blue and merged-red blocks since genesis. Used by covenants as a monotonic clock because every node agrees on the value for any given block.
At Kaspa's current ~10 blocks per second, one hour of wall time corresponds to roughly 36,000 DAA-score units — though the exact mapping shifts with hashrate fluctuations and the difficulty adjustment algorithm's 2,641-block window.
The Checkin Path: Resetting the Timer
The inheritance timer starts ticking the moment a UTXO enters the vault. If the owner does nothing, the UTXO's age will eventually reach inheritDelay — and the heir can claim the funds.
To prevent this, the owner periodically calls the checkin path:
checkin(hotSig):
require(tx.inputs.length == 1) // single-input invariant
verify(checkSig(hotSig, hot))
→ VAULT mode, dest unchanged
The checkin transaction spends the vault UTXO and creates a new one at the same address with identical state. The critical effect: the new UTXO's age resets to zero. The inheritance timer restarts from scratch.
Because checkin is a VAULT-to-VAULT transition with no change in destination, the funds stay in the vault. The owner only needs to broadcast a checkin once every inheritDelay period — think of it as a cryptographic "I'm still here" signal.
From the watcher's perspective, this is the simplest path to monitor. The Kaspa Forge backend polls the vault UTXO every 10 seconds via gRPC, compares the current age against inheritDelay, and sends reminders when the owner hasn't checked in for 80% of the timeout window.
Two Inheritance Paths: Automatic vs. Signed
Kaspa Safe offers two modes for inheritance, chosen at vault creation via the autoInherit flag. Exactly one is active at any time.
Auto-inherit (autoInherit = 1):
inheritAuto():
require(autoInherit == 1)
require(age >= inheritDelay)
require(heir != [0; 32]) // heir must be set
→ output to P2PK(heir), no signature needed
This is a keyless path — anyone can broadcast the transaction once the timer expires. The funds go to a P2PK address derived from the heir's public key. No one needs to sign; the covenant script itself determines the output. The single-input invariant and feeBudget cap (max 0.1 KAS) prevent misuse — the watcher can't redirect funds or drain the vault in network fees.
In practice, Kaspa Forge's watcher detects when age >= inheritDelay and automatically broadcasts the inheritAuto transaction. The heir receives an email notification (set during vault creation) that funds are available at their P2PK address. They need only import or derive the corresponding private key to spend.
Signed inherit (autoInherit = 0):
inheritSigned(heirSig):
require(autoInherit == 0)
require(age >= inheritDelay)
require(heir != [0; 32])
verify(checkSig(heirSig, heir))
→ output to P2PK(heir)
Here the heir must actively claim the funds by signing with their private key. The watcher can still send notifications, but the transaction won't go through without the heir's signature.
The design tradeoff is clear: auto-inherit is more resilient (the heir doesn't need technical sophistication or even to know the funds exist until they arrive), but it means anyone who can broadcast the keyless transaction can trigger the release — which is the entire point of the mechanism. Signed inherit requires the heir to act, adding a layer of intent but also a point of failure if the heir loses their key.
Setting heir = [0; 32] (32 zero bytes) disables inheritance entirely. The vault then has no inheritance paths — only the owner's withdrawal and alarm paths remain active.
How the Watcher Assists (and What It Can't Do)
The off-chain watcher is a 10-second polling loop in the Kaspa Forge backend. For each registered vault, it:
1. Fetches the current UTXO via gRPC against the node's UTXO index. 2. Computes the current age from the UTXO's creation DAA score relative to the virtual block's DAA score. 3. Compares age against inheritDelay (and delay for withdrawals). 4. Dispatches alerts when thresholds are crossed.
For inheritance specifically, the watcher fires at two stages:
- Checkin reminder at ≥80% of
inheritDelay: "Your vault's checkin timer is running low." This goes to all connected channels — Telegram bot, email, and Web Push. - Inheritance triggered: when
age >= inheritDelayandautoInherit = 1, the watcher broadcasts theinheritAutotransaction and notifies the heir via the email stored at registration.
Because inheritAuto is keyless, the watcher can broadcast it without holding any private key. The transaction's outputs are fully determined by the covenant script. Even if Kaspa Forge's servers go offline permanently, any party with access to the vault's public parameters can broadcast the same keyless transaction against any Kaspa v2+ node.
Kaspa Safe's dead-man switch is part of a non-custodial vault where on-chain operations are free forever. You set the checkin interval, choose automatic or signed inheritance, and designate an heir — all in the browser. Keys never leave your device, and the covenant enforces the rules even if Kaspa Forge disappears. If you've been thinking about a practical plan for your KAS, create a vault and see how it works.
The Full Vault Lifecycle With Inheritance
To see how inheritance fits into the vault's complete operation, here are all seven spending paths:
| Path | Signature required | State transition | Purpose |
|---|---|---|---|
initiate(hotSig, destPk) | Hot key | VAULT → UNVAULTING | Start a withdrawal |
cancel(alarmSig) | Alarm key | UNVAULTING → VAULT | Cancel a theft in progress |
complete() | None | UNVAULTING → dest | Finalize withdrawal after delay |
checkin(hotSig) | Hot key | VAULT → VAULT | Reset inheritance timer |
inheritAuto() | None | VAULT → heir | Auto-inherit after timeout |
inheritSigned(heirSig) | Heir key | VAULT → heir | Claim inheritance with signature |
migrate(hotSig, alarmSig) | Both keys | Any → any | Move vault, rotate keys |
The inheritance paths only execute while the vault is in VAULT mode. If the owner initiates a withdrawal (VAULT → UNVAULTING), the inheritance paths are blocked — the owner must either complete the withdrawal or use migrate with both keys to regain full control. This interaction is intentional: if someone steals the hot key and initiates a withdrawal, the alarm key can cancel it back to VAULT mode, where the checkin and inheritance paths resume.
Offline Recovery: Death of the Service ≠ Death of the Funds
A critical property of the dead-man switch is that it's enforced on-chain. Kaspa Forge's watcher is a convenience layer, not a dependency. If the service disappears:
1. Keyless paths still work. Anyone with the vault's P2SH address and the covenant bytecode can construct and broadcast complete() or inheritAuto() against any Kaspa v2+ node. 2. The .age key-file backup survives. The Desk profile — including the hot key, alarm key, and heir information — is encrypted with a scrypt passphrase into an ASCII-armored .age file. This file is compatible with the open-source age CLI tool. 3. The vaultctl CLI tool is open source. It builds any of the seven vault transactions offline and submits them to any public node. The vault selftest suite covers all 18 contract checks.
The inheritance mechanism survives the team, the servers, and the domain. The covenant's rules are burned into the blockchain.
Honest Limitations
No design is without tradeoffs:
DAA score ≠ wall clock. The inheritDelay is measured in DAA-score units, not hours or days. If the network hashrate changes significantly, the real-world duration shifts. A 30-day inheritDelay at current hashrate might stretch to 33 days during a hashrate drop, or shrink to 27 days during a surge. The DAA's 2,641-window smoothing helps but doesn't eliminate drift.
The heir must be reachable (signed mode). If autoInherit = 0, the heir needs their private key and must be aware enough to claim. If their contact information changes after vault creation, the notification may not reach them — though the on-chain mechanism still works regardless.
Single heir, no partial splits. The vault sends everything to one heir address. Splitting inheritance among multiple recipients requires multiple vaults or off-chain arrangements.
heir = [0; 32] means no inheritance. If the owner creates a vault without setting an heir, there's no recovery path if they become unavailable — the funds are effectively locked unless migrate with both keys is still possible.
v3 output guard is soft. The covenant enforces the value of outputs[0] but not tx.outputs.length. A crafted transaction could add additional outputs within the feeBudget cap. Official Kaspa Forge builders always produce canonical single-output transactions; this limitation is flagged for the v4 audit cycle.
The Design Philosophy: Trust Math, Not Institutions
The dead-man switch pattern predates cryptocurrency by centuries — dead man's handles on trains, dead-man switches on detonators. The blockchain version adds two properties the physical versions never had:
1. The rules are public. Anyone can inspect the covenant bytecode and verify the inheritance conditions. There's no hidden executor, no secret amendment to a will. 2. The enforcement is automatic. No judge, no probate court, no lawyer's letter to an exchange. When the timer expires and the conditions are met, the blockchain executes.
This doesn't replace estate planning — a smart contract can't file a death certificate or deal with tax authorities. But it solves the narrow technical problem of *how does the money move* without introducing custodial trust. For self-custody-minded KAS holders, that's the part that matters.
FAQ
Can Kaspa Forge or the watcher redirect my inheritance?
No. The covenant script — not any server — determines where funds go. The watcher can only broadcast the keyless inheritAuto transaction, which sends funds exclusively to the heir address baked into the on-chain contract. It cannot change the destination.
What if I lose my hot key?
If you still have the alarm key, you can use the migrate path (requires both keys) to move funds to a new vault with a freshly generated hot key. If both keys are lost, funds can only be recovered if inheritance is enabled and enough time passes for the heir path to activate.
How precise is the DAA-score timer?
DAA score is not wall clock. At roughly 10 blocks per second, one hour is approximately 36,000 DAA-score units, but hashrate fluctuations shift this ratio. The DAA's 2,641-block window smooths short-term variance. For a 30-day inheritDelay, drift of ±3–5 days is realistic.
Can I change the heir after creating the vault?
Yes, through the migrate path (both hot + alarm keys required). Migrate lets you move all funds to a brand-new vault with different parameters — a new heir, a different inheritDelay, or both — in a single transaction.
What happens if Kaspa Forge shuts down permanently?
The covenant lives on-chain. Keyless paths (complete, inheritAuto) can be broadcast by anyone against any Kaspa v2+ node. The open-source vaultctl CLI builds and submits these transactions from a terminal. Your .age key-file backup decrypts with the standard age tool.
Does the heir need a Kaspa wallet to receive funds?
The heir needs the private key corresponding to the pubkey designated at vault creation. If autoInherit is enabled, funds arrive at the heir's P2PK address without any action; the heir just needs to import that key into any Kaspa wallet to spend.
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
