KaspaForge
Networkchecking DAAchecking Nodechecking
CovenantsToccata KeysLocal CustodyNone
Statuschecking
Security GitHub
Security · verify, don’t trust

Security Center

Everything that decides whether Kaspa Forge can be trusted with your money, in one place — the real hashes, keys and test numbers, and how to check every one of them yourself. Kaspa Forge is non-custodial: the funds live in open-source on-chain covenants, and this page is our attempt to make that verifiable rather than a promise. Last reviewed: July 23, 2026. Security contact: kaspa@officeforge.co · security.txt.

Both covenants are open source and unaudited — they have passed our own on-chain and adversarial tests, but no external audit yet. Non-custodial: we never hold your funds and no support desk can reverse a transaction, so use amounts you're comfortable trusting to code.
Trust boundary

What lives where

Your device

Keys are generated and stay here — in the password-locked encrypted profile or on a separate alarm card. Every transaction is signed locally; your password and private keys are never sent anywhere.

Our server

Sees public parameters, signed transactions and ciphertext only: encrypted chats, encrypted sync blobs, listing media. Nothing stored here can move funds.

Kaspa L1

Holds the coins and the covenant scripts. Delays, payout paths and timeouts are enforced by Kaspa consensus — not by this website.

Product enforcement

What the covenant enforces — and the most we could ever do

productthe covenant enforcesthe operator can at most
Safea withdrawal leaves only through your delay window to the destination locked at start; the separate alarm key cancels it; single input + fee cap on every pathwatch the chain, broadcast the already-signed keyless completion, send alerts
Escrow10 fixed payout paths that pay only the buyer, the seller or the visible fee address — no third party can ever be paidas arbiter, pick buyer / seller / split within an open dispute
Depositthe same escrow covenant with the depositor as the default: no claim by the deadline → automatic returnthe same arbiter limits, only while a claim is open
Marketthe Buy button opens the same escrow covenant — payment never passes through usmoderate listings out of the catalog; a funded deal’s coins are untouchable
Boardsevery text post is a signed Kaspa transaction; tips pay the post’s own key directlyhide content from our mirror (tombstone) — the on-chain record remains
These are the same invariants as §1, per product. They hold regardless of whether you trust us; the honest caveat is that the covenants are open source but unaudited — see the warning above.

1. The trust model

Kaspa Forge holds no custody of your coins. Money sits in a Kaspa on-chain covenant — a script enforced by Kaspa consensus, not by our server. Signing keys exist only in your browser/app: inside the encrypted Desk profile or, for separate-storage Safe alarm keys, on your alarm card. They are never sent to us; the client-side key boundary is documented from browser memory through transaction signing. Forge Sync uploads only an end-to-end encrypted safe projection and never includes Safe alarm keys — even when one is stored in the encrypted profile. What that buys you, stated as hard invariants:

  • The server cannot steal. No vault or escrow private keys, and no seed, ever live on the server. The keyless covenant paths (a vault's complete and inheritAuto; an escrow's autoRelease and timeout) hard-bind their output to a fixed recipient, so even our own watcher can only push funds where the contract already says they go.
  • The arbiter cannot steal. The escrow covenant has no path to any third party — every one of its 10 spend paths pays only the buyer, the seller, or the fixed service-fee address. A compromised or coerced arbiter still cannot express a theft as a valid transaction; the worst they can do is pick one of buyer / seller / split.
  • A thief with only your hot key gets nothing fast. A vault withdrawal only leaves through the unvault delay window to a fixed destination, and the separate alarm key cancels it. Keeping that key on its own card is the safer default; storing it in the encrypted profile is an explicit convenience trade-off.
  • The watcher is a liveness service, not a custodian. It watches the chain and broadcasts the already-signed keyless paths (auto-release, inheritance, timeout) and sends alerts — it holds no key that can redirect funds.
  • Covenants are P2PK-only and non-composable. Outputs bind to plain pay-to-pubkey scripts; the covenants cannot be chained or wrapped into a larger contract that changes their rules.
  • Single-input on every path. Every entrypoint of both covenants asserts tx.inputs.length == 1 and an on-chain fee-budget cap (0.1 KAS), closing a multi-UTXO siphon and preventing a transition from being burned into the network fee.
  • The service is a convenience, not a dependency. If our site disappears, your funds do not: the contracts live on-chain. Safe recovery uses the offline decryptor and vaultctl; Escrow and Deposit recovery use the public recovery-kit/dealctl. Both work against an independent Kaspa node — see §10.

Full architecture and the annotated invariant list live in the docs; the contract sources below are the ground truth.

2. The contracts & their hashes

Two Silverscript covenants run everything. Both are published in full in our public repository. The SHA-256 below is of the covenant source file as published — it lets you confirm that the code you audit is the code we ship.

vault.sil — the Kaspa Safe vault covenant
versionv3 — inheritance (auto / signed), migrate path
spend paths7 — initiate · cancel · complete · checkin · inheritAuto · inheritSigned · migrate
sha-256a47cb298f60d688427585f9f7b443fddd3bef44c6ec87ebf35648897f7d0220b
escrow.sil — the Kaspa Escrow / Гарант covenant
versionv1 — 10 fixed payout paths
spend paths10 — release · refund · mutual · dispute · autoRelease · arbitrate{ToBuyer,ToSeller,Split} · timeout{ToBuyer,ToSeller}
sha-25665d4b6bb3c516647b72a873dab1272445c498f8b17bfba19ec15519726dcb4a0
Why not a single "deployed contract hash"? A covenant's on-chain script prefix is the source plus your own parameters (your pubkeys, delay, heir, fee budget, deal terms), so every vault and every deal has a different script hash — by design. The stable, auditable thing is the source above; the per-safe / per-deal script is derived from it deterministically by the open-source tooling, and your Desk shows the exact address you funded. See §3 to reproduce it.

3. Verify a contract yourself

Everything needed for party-side verification and recovery is public in github.com/Kaspaforge/kaspaforge: both .sil sources, vaultctl for Safe, and the hosted-free recovery-kit with the shared Rust core and dealctl for Escrow and Deposit. The operator-only escrowctl is not presented as a public recovery tool.

Confirm the source hash matches what this page claims:

# after cloning the repo
sha256sum contracts/vault.sil contracts/escrow.sil
# expect:
# a47cb298f60d688427585f9f7b443fddd3bef44c6ec87ebf35648897f7d0220b  contracts/vault.sil
# 65d4b6bb3c516647b72a873dab1272445c498f8b17bfba19ec15519726dcb4a0  contracts/escrow.sil

Run the public verification suites. The tools pin Silverscript at rev 26e3b9f. The Safe selftest and Deal Recovery core execute valid and adversarial paths inside the Kaspa VM; the recovery vectors also prove that browser/WASM, core and CLI derive the same addresses and transaction bytes:

# needs Rust (rustup.rs), protobuf-compiler, clang
cd vaultctl && cargo run --release -- selftest  # Safe: 25 checks
cd ../recovery-kit
cargo test --locked -p kaspa-forge-contracts      # 33 tests: unit + VM + parity
cargo test --locked -p dealctl                    # 33 tests; simnet E2E is opt-in

Reproduce your own safe's address. Decrypt your full .age profile offline, extract the Safe record as vault.json, then run vaultctl status --recovery vault.json. It rebuilds the covenant and prints the same address your Desk funded — proof that the deployed script is exactly this source instantiated with your parameters, with no server in the loop.

Verify and recover your own deal without giving the online machine a key. Offline dealctl watch creates a public watch file; online prepare --watch fetches the covenant UTXO; offline signing binds that package to the recovery record; online submit broadcasts the already-signed transaction. The exact four-step flow and checksum verification are in the Recovery hub.

4. Public keys & addresses

These are the only long-lived service values baked into escrow deals. Both are public by nature — an x-only public key and a Kaspa address. There is no service private key you need to trust: the arbiter key only lets the arbiter choose among buyer/seller/split, and the fee address only ever receives the visible service fee.

arbiter pubkey (x-only)43eec216c3c93e4c0565eb53aae1e4674d567111661baf5eaa2df405316eaa2e
escrow fee addresskaspa:qq3manh4l3yj69hc062wz5a86h6qjffx7nuh9ldkdjqr5kaxm4zy6sh2lksln

When you create or join a deal, these exact values are written into the covenant you fund — you can confirm them in your key file and against the on-chain deal.

5. Tests

Automated test suites (measured July 23, 2026). These counts come from fresh locked, all-target runs. Hosted/runtime suites and independently publishable recovery suites are shown separately so the public evidence is not hidden inside one total:

server crate335 passed · 0 failed · 5 ignored
browser/WASM crate38 passed · 0 failed
runtime subtotal373 passed · 0 failed
public recovery core33 passed · 0 failed
public dealctl33 passed · 0 failed · 1 opt-in simnet E2E

Consensus and recovery evidence. Safe has 25 public VM self-checks. The public Deal Recovery core's 33 tests include 9 Kaspa-VM tests and 2 deterministic parity vectors. The release review also passed the opt-in hosted-independent simnet E2E through extract → verify → watch → prepare → offline sign → submit, with exact on-chain balance deltas.

6. Reproducible builds & the app

The WASM vault/escrow core is built from source with wasm/build.sh (wasm-pack, release). The Deal Recovery Kit has one locked Cargo workspace, a fail-closed allowlist, whole-tree leak scan and RECOVERY-SHA256SUMS; it can be built from the repository root with cargo build --release --locked -p dealctl. Hosted server, chat/media, moderation, Telegram and operator/admin surfaces are outside that package.

No Android APK is currently distributed. The previous packaged builds were retired because they no longer represent the current Kaspa Forge product. Do not install an old package from a cache or third-party mirror; use the browser/PWA version until a current build is released.

The web app runs in your browser. Its Content-Security-Policy restricts script and network destinations and reduces the blast radius of an injection, but it is not a substitute for verifying the client code and keeping an independently checked recovery kit.

7. Known limitations

Honesty is part of the security story. These are the real edges of the current design:

  • Unaudited covenants. The contracts are open source but have not had an external audit yet. Escrow deals are enforced to a 50 KAS minimum.
  • Hosted web delivery is still a trust surface. While using the live site, you trust this origin to deliver the published client bytes. CSP is defense in depth, not proof against a compromised first-party release. Keep a verified recovery kit and check its checksum before an emergency.
  • Escrow needs an active buyer. A dispute must be opened within the dispute window. If the window passes with no dispute, funds auto-release to the seller — the buyer must act in time.
  • Lose your recovery material, lose access. There are no accounts and no password reset. Keep a full encrypted .age export and its password separately; for a separate-storage Safe, keep its alarm card too. Forge Sync is not a replacement: it cannot bootstrap an empty device and never transfers alarm_sk.
  • The service token is a capability. The token in your key file authorizes management API calls for your vault/deal; anyone who obtains it can call those endpoints (it still cannot move funds outside the covenant's fixed paths). It is not rotated automatically. Detail in the privacy policy.
  • Alerts require both access and a delivery channel. The first 30 days are a free trial; after that monitoring is 100 KAS/year. Trial or payment alone does not deliver anything: connect Telegram or an owner email for that Safe. Without a channel, no alert can arrive. Alerts also stop if our service is down; on-chain safety does not depend on them.
  • You evaluate your counterparty. In Escrow and the Marketplace we are not a party to the deal and do not vet goods, identity or solvency; the arbiter rules only within buyer/seller/fee.

8. Contract change history

Every change to the covenant sources, newest first (from the repository git log):

date file change
2026-07-10vaultmigrate path added (both signatures = instant full authority: upgrade / key rotation / exit)
2026-07-10bothon-chain griefing cap: feeBudget ≤ MAX enforced in every path (audit 07-11)
2026-07-10bothfee budget became a constructor parameter + two require()s from the audit
2026-07-10bothsingle-input invariant added to all paths (multi-UTXO anti-siphon)
2026-07-07vaultheader brought up to v3 (auto/signed inheritance)
2026-07-05escrowescrow.sil v1 — 10 paths (release/refund/mutual/dispute/autoRelease/arbitrate×3/timeout×2)
2026-07-04vaultv3 inheritance (auto/signed, chosen at creation)
2026-07-04vaultfirst on-chain vault (genesis covenant accepted by consensus)

The authoritative, complete log is the git history of contracts/vault.sil and contracts/escrow.sil in the public repository.

9. Responsible disclosure

Found a vulnerability? Please report it privately and give us a chance to fix it before it becomes public.

  • Email kaspa@officeforge.co with enough detail to reproduce (a proof-of-concept, affected component, and impact).
  • Do not post it publicly or exploit it against real users' funds while we work on a fix.
  • We aim to acknowledge reports quickly and will keep you updated on the fix and timeline. We will credit reporters who want it.

Machine-readable contact per RFC 9116: /.well-known/security.txt.

We do not run a paid bug-bounty program and make no promise of payment. This is a good-faith responsible-disclosure channel — we simply ask you to report privately, and we will act on it.

10. If something goes wrong

Because the contracts live on-chain, you can act even if our site is down:

  • Vault recovery (offline): decrypt the full .age profile locally, extract vault.json, then follow the vault recovery guide. vaultctl can check in, cancel a theft, complete a withdrawal, claim inheritance or migrate against any Kaspa node.
  • Escrow or Deposit recovery: verify the published recovery-kit checksums, extract and verify the deal offline, create a key-free watch file, prepare online, sign offline, and submit online. Follow the four-step dealctl guide; the private key never needs to touch the networked machine.
  • Suspected theft of a vault hot key: use the alarm key from its card or full local profile to cancel the in-flight withdrawal, then migrate to a fresh vault. A synced second device does not have this key unless you imported a full export from the creation device.
  • Found a security bug: do not post it publicly — email kaspa@officeforge.co (see §9).

Related: Terms · Safe privacy · Escrow & Market privacy · Docs. Questions: kaspa@officeforge.co.