Skip to main content
Templates are settlement product parameter packs. The state machine itself is not configurable - it is fixed in code (dvp/v1) and pinned on every settlement at creation. A template configures policy on top of the machine: the default timeout, compliance providers, required party roles, and what the engine does in each state. Templates are global - they are owned by KeyStone, not individual platforms. All platforms share the same set of templates. Templates are created and managed by KeyStone administrators; platform users browse available templates and reference them when submitting instructions via the API.
The contract does not know about templates. Nothing from the template is encoded on-chain - the KeystoneSettlement contract implements the chain-owned part of the machine natively, and registration carries only legs (with bound recipients and deposit keys), party hashes, and the timeout.

Template configuration

A template’s config object is the full parameter pack:
The schema is strict: state-graph keys (states, transitions, initial_state, …) are rejected. States and transitions live in the machine, not the template.

Key sections

Machine

machine selects which code-fixed machine settlements created from this template run (currently dvp/v1). The value is pinned on the settlement as machine_version at creation - in-flight settlements never change machines, and breaking machine changes ship as a new version rather than mutating dvp/v1.

Timeout

timeout_seconds is the default settlement deadline (now + timeout_seconds) when the caller does not pass an explicit timeout_at. After on-chain registration the deadline is enforced by the contract itself: deposits and execution are only accepted strictly before it, and claimTimeout (operator or any depositor, not pausable) takes over at and after it.

Actions

Each machine state can have an action the engine executes when a settlement enters that state: Action keys must be engine-actionable (non-terminal, engine-owned) dvp/v1 states - the only states the engine drives into and can act on. Binding an action to a chain-owned, admin-owned, or terminal state is rejected at validation (the config raises), not silently accepted.

Compliance

compliance.entity_providers and compliance.wallet_providers list the screening providers the compliance action runs (lseg_worldcheck for entities, cipherowl for wallets). A compliance_check action with "resolution": "immediate" must name at least one provider across the two lists - a template whose gate would screen nobody and clear is refused with 422 at create and update. Leave both lists empty only when the template binds no compliance_check action, or binds it with a non-immediate resolution (a manual decision gate resolved through the compliance-decision endpoints).

Roles

required_roles drives party validation: exactly one party per role at creation, one instruction per role in the paired flow.

Slugs

Every template has a unique slug - a short, human-readable identifier (e.g. cross_platform_dvp, repo_open_tri_party). Slugs provide a stable reference that does not change across template versions. When submitting an instruction, you reference a template by its slug.

Versioning

Templates are versioned. Every create and update stores an immutable snapshot of the config at that version, and each settlement pins the current version at creation (visible as template_version on the settlement). The pin is binding: the engine and every decision endpoint resolve the settlement’s pinned config snapshot, never the live template row. A template update only affects settlements created after it - a settlement that is already running keeps the exact rules (timeouts, compliance providers, action bindings) it started under, reconstructable at any time from its template_version.

Different settlement products, same machine

Different products are different parameter packs over the same machine: The settlement engine and the contract process all of them identically - same states, same transitions, same ownership rules.