Kaspa's Toccata activation brought covenants to mainnet: UTXOs whose spending scripts can inspect the transaction that spends them — reading output values, script public keys, and the active outpoint to enforce rules beyond simple signature checks. Writing those scripts by hand in raw stack-machine opcodes is fragile and hard to compose. The Kaspa covenant toolchain — SilverScript and Argent — exists to turn that raw scripting surface into something a developer can reason about, measure, and audit. This article explains both layers, how artifacts flow from compiler to runtime, what admission checks a covenant must pass before it touches real money, and where Kaspa Forge draws the line between R&D tooling and live production contracts.
What Problem Does a Covenant Toolchain Solve?
A covenant is a UTXO with a script that constrains not just *who* can spend it, but *how* — which outputs receive funds, what state the successor carries, whether a time lock has elapsed. On Kaspa, this is enabled by KIP-20 introspection opcodes and the CovenantID commitment scheme that binds each covenant instance to its on-chain origin.
Raw Kaspa Script is a stack machine. Writing a multi-branch covenant — with state transitions, fee caps, age gates, and payout rules — in raw opcodes is like writing a protocol parser in assembly: possible, but the surface area for bugs grows faster than the code. You need three things:
1. A language that expresses covenant logic at a higher level than opcodes. 2. A compiler that produces deterministic, pinnable bytecode. 3. A runtime that can build valid transactions from auditable artifacts without re-running the compiler.
SilverScript provides (1) and (2). Argent adds a layer on top and provides (3). Together they form the Toccata developer toolchain for programmable spending conditions on Kaspa's UTXO model.
SilverScript: The Covenant Compiler
SilverScript (kaspanet/silverscript) is the official Kaspa covenant compiler. A .sil source file describes a script with typed state regions, temporal constraints, introspection helpers, and branching logic. The compiler emits Kaspa Script bytecode — the exact bytes that will live on-chain inside a P2SH address.
Key capabilities on the current pinned baseline:
- State regions with splice ABI. A fixed-size byte region that the script reads from the spending input and writes into the successor output. The Arena Game covenant, for example, uses a versioned 108-byte state region to track both player and dealer hands, card indices, and game phase — all encoded as raw bytes that the script decodes with
OpNum2Binand arithmetic opcodes. OpBlake3(0xd9). Available under covenants, enabling on-chain blake3 commitment verification without protocol changes. Arena uses this to verify that a dealer's deck commitment matches the cards actually dealt.- Temporal types.
<delay> OpCheckSequenceVerifyfor age gates — the script can require that a UTXO has existed for N blocks before a timeout path unlocks. This is how Arena's permissionless timeout branches work: a player or dealer who disappears leaves their bond recoverable after a delay. - Introspection. Scripts can read transaction fields — output values, script public keys, the active outpoint — to enforce value conservation and payout rules. Every output in a covenant transaction is accounted for: who receives what, and within what fee cap.
- ZK verification.
r0.*andg16.verifyopcodes allow on-chain Groth16 proof verification. Arena's HOSTED mode uses this path: the dealer submits a zero-knowledge proof that the deck was shuffled fairly, and the covenant verifies it on-chain.
The compiler is deterministic: the same .sil source on the same SilverScript commit produces byte-identical output. This is not a convenience — it is a security requirement. A single byte difference changes the P2SH address and therefore the covenant identity on-chain. Pinned commits, BLAKE3 template hashes, and golden test vectors all exist to enforce this determinism.
SilverScript also defines the KCC (Kaspa Covenant Contracts) standard templates — KCC1, KCC2, and KCC20 are merged into main as Draft specifications. These are reference implementations, not production contracts. The Kaspa Forge live contracts use their own frozen SilverScript pins, not the KCC templates.
Argent: Multi-Actor Applications on SilverScript
Where SilverScript compiles one script at a time, Argent (argent-lang/argent) models an application as a graph of covenant actors that can change state atomically in a single Kaspa transaction.
An Argent .ag application graph declares actors, their state types, entry points, and transitions. The compiler resolves the graph, generates SilverScript .sil for each actor, and produces a portable artifact — a JSON bundle (artifact.json plus manifest.json) that contains everything a runtime needs to build transactions: script bytes, state spans, template hashes, dependency IDs, and witness recipes.
This is the core architectural shift:
.ag application graph
↓ argent compiler
plain auditable .sil + portable artifact + manifest
↓ argent-runtime / ArtifactBundle / TxContext
atomic multi-actor Kaspa transaction
The artifact acts like a verified recipe: an auditor reviews it once, and the runtime follows it to build transactions without needing the compiler or its AST. TxContext carries sequence, lock time, lane and payload metadata, and checks compute and transient mass before the transaction is signed.
Cross-app linking. Argent supports importing actors from separately compiled applications. The dependency is recorded as an exact artifact ID in the manifest. At runtime, ArtifactBundle rejects a missing or mismatched dependency. Two teams can independently version and audit their covenant code, then link them without recompilation — the artifact ID is the trust anchor.
Constrained genesis spawns. The spawns primitive lets an existing covenant input authorize the creation of a new covenant in the same transaction. The script reconstructs the KIP-20 CovenantID preimage from the active outpoint and consensus-derived output values, proving that the declared genesis output group is complete and correctly ordered. The parent can then write the child's covenant-id into its own successor state. For Kaspa Forge, this maps naturally to patterns like Room → Game or Listing → Escrow.
Route planner and explicit value economy. Each actor output has a name and must explicitly reference its .value or declare unrestricted(output.value). This is not a full value-flow proof — the check is syntactic and entry-scoped — but it catches accidentally orphaned outputs and makes sum audits more tractable than hand-written scripts.
Admission Checks: From Compiler to Production
Argent and SilverScript are tools, not guarantees. Before any covenant goes live on Kaspa Forge, it passes through a documented admission sequence — a pre-flight checklist where every item must clear:
1. Pin. Exact commit of Argent, SilverScript, Rust toolchain, and rusty-kaspa. No floating git dependencies. 2. Reproducibility. Two clean builds produce byte-identical .sil, artifact, manifest, and script bytes. Paths and line endings must not influence output. 3. Inspect budget. argentc inspect reports script size, state span, template hash, opcode count, signature script estimate, and compute mass for every entry point. 4. Artifact trust. Script bytes, state span, template hash, dependency IDs, and imported actor receipts are independently verified. Until upstream closes the linked-actor receipt gap, the verifier must close it manually. 5. Consensus tests. Positive and mutation matrices pass not only builder tests but the local TxScriptEngine and funded TestConsensus on the target Toccata pin — real consensus execution, not just script simulation. 6. Application invariants. Exact outputs, value conservation, fee caps, signature ownership, DAA and sequence locks, liveness, and recovery are checked separately. The compiler does not infer them. 7. Audit. Generated .sil, artifact, runtime, and source application are reviewed. A delta audit runs on every pin bump. 8. Versioning. Any change that alters script bytes produces a new P2SH address. Live UTXOs are never "recompiled" — migration means new addresses and user action.
This sequence is not optional ceremony. Each gate catches a class of failure that the layers above it do not.
How Kaspa Forge Uses the Toolchain
The relationship between the toolchain and Kaspa Forge products is layered, and the boundaries are hard:
Live contracts — frozen SilverScript, not Argent. Kaspa Safe (vault.sil) and Kaspa Escrow (escrow.sil, also serving Deposit and Marketplace deals) are pinned SilverScript contracts with their own generators, golden vectors, and consensus test suites. Arena Room and Game covenants are similarly frozen with their own pins, ZK journal, timeout logic, and payout matrices. These contracts predate Argent integration and will not be recompiled — any new version would be a new P2SH family requiring user migration.
R&D — Argent as design checklist. Argent enters the architecture review for a new Kaspa Forge service when the state machine needs: two or more stateful covenant actors changing atomically; a parent authorizing the full genesis of a child covenant; cross-app linking between independently versioned components; or portable artifacts for a browser or native builder without compiler dependencies.
Desk — future artifact boundary. A pinned artifact bundle could eventually serve as the verify-and-build input for Desk: the wallet loads the artifact, checks the app ID and dependency IDs, and builds the transaction from audited recipes. This requires stable decoder APIs, linked receipts, and launch proofs that do not yet exist.
Tokens — manual SilverScript for v1. The planned fixed-supply token covenant is a single frozen asset contract without a live minter. Hand-written SilverScript is shorter and avoids depending on the unresolved KCC20 bootstrap path.
The live Kaspa Safe vault and Kaspa Escrow run on frozen, independently audited SilverScript contracts — not Argent. If you want to see covenants working in production today, those are the surfaces to explore. The toolchain described here powers the R&D behind future Kaspa Forge services, and its admission gates are the reason the live contracts stay on their own pinned generators.
Trade-offs and Honest Boundaries
The toolchain is powerful, but its limits are real and worth stating plainly:
- Argent is not production-ready. Upstream explicitly states the project has no releases, no tags, and no audit. The artifact schema still changes in breaking commits. PR #44, which adds bounded ranges for
consumesandemits, remains a draft — its runtime transaction construction is incomplete. - SilverScript KCC templates are Draft. KCC1, KCC2, and KCC20 are merged into
mainbut not finalized. KCC21 is an open PR. None of these are the contracts running on mainnet. - The toolchain does not replace audits. Generated
.silmust be independently reviewed. Compiler correctness, fee semantics, timelock enforcement, and value conservation are application-level invariants that no compiler infers automatically. Claiming otherwise would be dishonest. - Linked actor receipts are incomplete. Cross-app admission cannot yet be fully trusted as a security boundary — the verifier must close the gap manually or the design must avoid relying on it.
- Rust toolchain must be pinned. Argent's upstream CI passes on Rust 1.94.0; Rust 1.96.0 introduces a breaking Clippy lint. Reproducible builds require the exact toolchain version as part of the manifest.
- Live contracts cannot be recompiled. Changing script bytes changes the P2SH address. There is no upgrade-in-place mechanism — migration means new addresses and deliberate user action.
The honest summary: SilverScript is live protocol technology that has been compiling and shipping Kaspa's covenant contracts to mainnet since Toccata. Argent is a promising R&D compiler that has already proven multi-actor composition works on the current Kaspa VM — constrained spawns, cross-app linking, and portable artifacts are real primitives tested against consensus. But Argent is not a dependency for any live money script today, and the admission gates described above are the mechanism that keeps it that way until the toolchain earns production trust through audits, stable releases, and closed receipt gaps.
Continue exploring
Kaspa Forge transaction architecture
Next useful step: continue with the protocol documentation
FAQ
What is SilverScript?
SilverScript is the official covenant compiler for Kaspa. It compiles .sil source files into Kaspa Script bytecode that enforces complex spending conditions — covenants — on UTXO outputs under the Toccata activation.
What is Argent?
Argent is a higher-level application compiler that targets SilverScript. It models multi-actor covenant applications as graphs, produces portable artifacts, and includes a compiler-free runtime for building atomic Kaspa transactions.
Are Kaspa Forge's live contracts written in Argent?
No. The live Kaspa Safe vault and Kaspa Escrow are frozen SilverScript contracts with pinned generators and independent audits. Argent is an R&D tool for future services, not a dependency for any live money script today.
Can I use Argent to write production covenants today?
Argent has no stable releases, no audit, and its artifact schema still changes in breaking commits. Upstream explicitly states the project is not release-ready. It is useful for research and prototyping, not for deploying money scripts.
What is a KIP-20 covenant?
KIP-20 is the Kaspa Improvement Proposal defining the covenant framework — transaction introspection opcodes and state handling that let a script inspect and constrain the transaction spending it. See the Kaspa wiki for the KIP process.
Does the toolchain remove the need for audits?
No. The toolchain helps structure and measure covenant code, but generated scripts must be independently audited. Compiler correctness, fee semantics, timelock enforcement, and value conservation are application-level invariants that no compiler infers automatically.
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
