Pre-production · unaudited · testnet-only. Nothing is on mainnet. Testnet evidence is perishable (testnets reset by design).

The covenant pattern library for Kaspa

Reusable covenant components you can drop into a Kaspa project: vaults, escrows, auctions, registries, token standards, access guards. Each one is real silverscript, with its own tests and a threat model. Browse the library, or start one in the wizard.

The library is written in Portrait, a small covenant language that compiles to silverscript. Both are open source (MIT) and maintained by the Stichting Kii Foundation, a Dutch non-profit that doesn't bill for anything.

Covenant Patterns Library

This is the part that saves you work: a catalogue of covenant patterns to reuse instead of writing from scratch, the Kaspa counterpart to Solidity's audited pattern libraries. Every pattern is real silverscript with a Portrait wrapper, golden tests, and a threat model, and it goes through the same portrait check as everything else here.

The .portrait catalogue

Vaults, escrows, auctions, registries, token standards, access guards. 35 covenant sources in all, 10 of them cross-layer (vProg) patterns. By family: finance 18, custody 3, governance 2, attestation 1, state 1, vprog 10.

Reusable Rust primitives

A companion crate library for the pieces you reach for constantly: ownable, pausable, timelock, a yield-vault profile, and more. A Solidity-to-Kaspa migration guide sits alongside it, under compliance-patterns/.

Not sure where to begin? The wizard turns a pattern and a few toggles into a .portrait file you can build on. Everything it produces has passed portrait check, which is a structural gate, not an audit.

How Portrait works

You write a covenant in Portrait: its state, its guards, its transitions. The compiler parses it, type-checks it, lowers it, and emits a .sil file (plus its CTOR JSON) that the real silverc accepts. Every stage in between is something you can read.

Twelve crates, one workspace

Each stage is its own crate, so you can see exactly what happens:

  • portrait-syntax, portrait-sema, portrait-ir: parse, check, lower
  • portrait-pounce, portrait-project, portrait-emit: project and emit the .sil
  • portrait-atelier, portrait-plan, portrait-verify: guest emit, planning, hallmarks
  • portrait-lens, portrait-compose, portrait-cli: verification, composition, the CLI

The CLI, in the order you'd use it

  • portrait check parses and runs the semantic checks
  • portrait prove discharges the model's VCs with z3
  • portrait compose checks a multi-covenant protocol
  • portrait validate-translation compares the model against the emitted .sil
  • portrait ship emits and compiles the artifacts. It does not deploy.

The two verifiers, and where they stop

Two verification engines ship with the compiler. Both make narrow, specific claims, and it's worth knowing where each one stops before you lean on it.

Lens

Lens works on your covenant model, not the compiled output. It generates verification conditions (value conservation, ranges, refinements, invariants, the spend path) and discharges them with z3, under the assumptions the M0 spec writes down (A1 to A4). Counter-models are checked fail-closed, and contradictory premises come back UNKNOWN rather than a false PROVED.

Where it stops: it proves the model, not the emitted .sil (validate-translation checks that correspondence, and only structurally), and it never runs on a DAG, so nothing it reports is a statement about on-chain behaviour.

Composer

Composer checks that several covenants wired together form a well-typed protocol. That is the whole claim: type-level safety of the composition.

Where it stops: it says nothing about liveness on a DAG, and it doesn't stand in for a deployed covenant. It's a type check, not a runtime.

Both engines have been through internal adversarial hardening: build, attack, fix, repeat. That is not external review. The M0 specs exist so that review can happen, and the stronger claims wait until it has.

Quick start

From the compiler workspace (portrait/portrait/): run the tests, engrave one of the examples, and hand the emitted .sil to the real silverc.

cargo test --workspace
cargo run --bin portrait -- engrave ../examples/counter.portrait
silverc --ctor ../examples/Counter_ctor.json -c ../examples/Counter.sil

If that last line exits 0, silverc accepted the covenant. It's the same check every pattern in the library has to pass.

Don't trust it, check it

Every number on this page traces back to a file, a command, or a testnet transaction. The trail lives in compliance-patterns/.

The library ships 35 covenant sources. Ten are cross-layer (vProg) patterns, and five of those ten are settled live on testnet-10; the other five are emit-verified only. If you want to dig in, three things are worth reading: FRONTIER-COMPLETE states the exact soundness claims for Lens and Composer; the M0 specs (the Lens encoding spec and the Composer design) are written so someone external can review them; and the settle txids themselves each carry is_accepted=true next to a rejected negative control.

Those TN10 txids are captured in PROVENANCE.json. They are perishable testnet evidence, not a permanent ledger, and nothing here is on mainnet.