Skip to content
 
 

Repository files navigation

Argent

Argent is an actor-based language and compiler for building stateful, multi-contract and multi-app applications on covenant-native UTXO rails.

Applications are expressed as transaction-wide state transitions over covenant UTXOs. Actors own typed state, entries consume and emit actors, and become defines the successor actors created by one atomic transaction. Inter-Covenant Communication (ICC) extends the same model across independently compiled apps.

Compiler foundation

Argent is built on Silverscript, the core foundation of this compiler. Silverscript provides the complete single-contract language and compiler stack, from typed contract source to Kaspa Script, together with the low-level builtins that make Argent's complex multi-contract and multi-app work possible.

Argent adds the application layer above that foundation. It turns .ag source into plain, auditable Silverscript contracts and portable artifacts consumed by argent-runtime. Together the layers handle state layouts, template commitments, routing, output validation, cross-covenant observation, virtual state expansion, and hidden witness material.

The design targets programmable UTXO systems with script-composition primitives such as OP_CAT and OP_SUBSTR, transaction introspection, and consensus-supported covenant identities (see Kaspa’s KIP-20 for a reference model).

Kaspa is the native target: .ag programs compile to Silverscript and ultimately execute on the native Kaspa Script engine. The language, artifact, and runtime layers keep Kaspa-specific assumptions explicit and separated where practical.

Project status

The project is still under active development and is not yet release-ready. Once Silverscript completes its audit and is released, advanced users who can review the generated .sil contracts will have a viable path to careful early production use. This requires understanding Argent's route semantics and compiler model well enough to verify that the generated contracts match the intended application. Argent itself will still need further audit and hardening before general production use.

The main pieces are present: compiler, generated Silverscript, portable artifacts, runtime transaction building, multi-actor routing, cross-app linking, constrained covenant spawning, actor enums, closed and open ICC, and virtual-slot state expansion.

.ag source
    |
    v
Argent compiler
    |
    +-- plain .sil contracts
    |
    +-- portable artifact
              |
              v
       argent-runtime
              |
              v
   atomic multi-actor Kaspa tx

Quick start

Run the standard local check loop:

./check.sh

Regenerate tracked example outputs and run the full check loop:

./check.sh --full

Build one app manually:

cargo run -- build examples/tickets.ag --out examples/build/tickets
cargo run -- build examples/stones/app.ag --out examples/build/stones
cargo run -- build examples/icc/kcc20_asset.ag --out examples/build/icc_kcc20_asset
cargo run -- build examples/icc/minter.ag --out examples/build/icc_minter
cargo run -- build examples/open_icc/agent.ag --out examples/build/open_icc_agent
cargo run -- build examples/open_icc/core.ag --out examples/build/open_icc_core

When one source file declares multiple apps, select the app to build by name:

cargo run -- build contracts.ag --app DexCore --out build/dex-core

Generated outputs include:

  • artifact.json: the portable Argent artifact
  • manifest.json: build metadata
  • sil/*.sil: generated Silverscript contracts

Inspect the compiled artifact without rebuilding it:

cargo run --bin argentc -- inspect examples/build/tickets

The report summarizes actor script, state, and template sizes, static opcode counts, entry arguments and generated witnesses, route metadata, and signature-script size estimates.

Generated .sil files compile as ordinary Silverscript. Within each contract, Silverscript provides the types, expressions, functions, arrays, loops, and control flow, then performs the final type checking and Kaspa Script compilation. Argent does not use Silverscript covenant macros.

Language at a glance

state TicketState {
    byte[32] owner;
    int units;
}

actor Ticket owns TicketState {
    entry transfer(byte[32] next_owner, sig owner_sig, pubkey owner_pk) emits next: Ticket {
        require(blake2b(byte[](owner_pk)) == owner);
        require(checkSig(owner_sig, owner_pk));
        require(next.value == self.value);

        TicketState new_state = {
            owner: next_owner,
            units: units,
        };

        become next <- Ticket(new_state);
    }
}

app Tickets {
    actor Ticket;
}

Argent uses type-first syntax for declarations and callable parameters. Bindings put the local name on the left. See Surface syntax conventions for the rules and examples.

Argent actors are not async actors with mailboxes or message queues. They are covenant objects that get consumed and recreated by transactions. The shared idea with actor models is state ownership: an actor's code is the only authority that can consume and mutate that actor's state.

Core terms:

  • state defines a persistent covenant state layout.
  • actor defines one contract template that owns a state layout.
  • entry defines a callable transition path.
  • delegate defines a non-leading check in a coordinated transition.
  • consumes names peer covenant inputs in the same transaction.
  • emits declares the authorized output handles for an entrypoint.
  • become is the terminal transition into successor actor state.
  • observes declares a foreign covenant view for ICC.
  • spawns declares a genesis covenant output group and binds its generated covenant id. A spawn target can be an actor in the selected app or an actor_type<State> value.
  • actor_type<State> identifies a runtime-selected actor implementation compatible with State.
  • actor enum defines a closed set of runtime-selected actor targets.
  • virtual slots and state X expands Base let concrete actors bind private digest-backed memory while preserving a shared base state layout.

Examples

For client-side examples, see argent-playground. It is a separate Rust project that depends on a neighboring Argent checkout and shows complete app compilation and transaction-building flows through argent-runtime.

Runtime

argent-runtime is the artifact-only consumer surface. It has no compiler dependency. It loads compiled artifacts, fills hidden witness material, builds covenant UTXOs, composes artifact bundles, and builds complete transactions from concrete actor inputs and outputs.

Classic single-app flow:

let builder = TxBuilder::new(&artifact)?;

let input_state = state! { count: 2 };
let output_state = state! { count: 5 };

// The covenant UTXO being spent.
let input_utxo = builder.covenant_utxo(
    "Counter",
    input_state.clone(),
    value,
    0,
    false,
    Some(covenant_id),
)?;

let context = TxContext::new()
    .actor_input(
        "Counter",
        input_state,
        EntryCall::new("bump").args(args![3]),
        outpoint,
        input_utxo,
        0, // sequence
    )
    .actor_output(
        "Counter",
        output_state,
        CovenantBinding::new(0, covenant_id),
        value,
    );

let tx = builder.build(&context)?;

Each input declares its sequence. Lock time, lane and gas, and payload can be set fluently on TxContext; their defaults produce a native transaction.

The runtime API is Argent-specific while the language settles. The lower-level Silverscript ABI and artifact boundaries are split into small crates so they can be kept portable. Multi-app ICC uses ArtifactBundle; the transaction context is otherwise the same for single- and multi-app transactions.

Why Argent

Kaspa covenants make it possible to build applications from several stateful UTXOs whose transitions compose atomically in one transaction. But hand-written multi-contract systems quickly accumulate mechanical obligations: state serialization, template hashes, route commitments, prefix/suffix witnesses, output ordering, observed covenant ids, and cross-contract state reads.

Argent makes the application graph source-level. Actors own state. Entries declare the peer actors they consume, the outputs they emit, the foreign covenants they observe, and the successor actors those outputs become. The compiler checks the declared state-machine edges and emits the Silverscript that performs the low-level validation.

Generated contracts stay as plain .sil files, and the artifact records the runtime recipe needed to build transactions against them.

How it works

The compiler parses .ag source into an actor/state model and lowers each actor to one Silverscript contract. Source state fields become the contract state layout. Compiler-generated fields and hidden entry arguments carry template receipts, route-family tables, observed-covenant witnesses, and expanded-state preimages.

become routes lower to output validation. Exact continuations can use cheaper script-public-key checks. Foreign or runtime-selected actors use template prefix/suffix witnesses or route-family tables. observes lowers to covenant input/output checks against another app. virtual slots lower to fixed digest fields, with concrete actors providing hidden preimages when they expand those slots into structured memory.

The portable artifact records the runtime recipe for all of this: script bytes, state layouts, type descriptors, route receipts, observed covenant metadata, hidden witness recipes, artifact ids, and interface fingerprints. argent-runtime consumes that artifact directly; it does not depend on compiler AST types.

Each app artifact also records the exact artifact ID of each direct app dependency. Runtime bundles reject missing or different dependency artifacts before they build a transaction.

Current status

What is useful today:

  • compiling .ag apps to auditable .sil
  • building tracked example transactions through argent-runtime
  • closed and open ICC examples
  • route-family and actor-enum examples
  • virtual-slot expanded state for open-agent style apps

What is still being built:

  • broader launch and bootstrap tooling
  • richer package and dependency tooling
  • stronger diagnostics and typechecking
  • generated app-specific builder APIs
  • broader hardening and negative-test coverage

Design notes can be found in docs/argent-design.md. ICC semantics can be found in docs/icc-semantics.md. Subtle generated-code security arguments are documented in Security invariants.

Contributing

Run ./check.sh --full before submitting changes. Open design questions and implementation sketches are collected in docs/followups.md; they are useful starting points for discussion and contributions.

About

Actor-based language and compiler for stateful, atomic, multi-contract applications on Kaspa and covenant-native UTXO rails.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages