Argent

The experimental actor-style direction for writing multi-contract Toccata covenant systems.

Argent is not a third road beside covenants and based apps.

It is a prototype for the next layer above Silverscript: write a multi-contract covenant system as actors, roles, routes, and typed transitions; lower it into explicit Silverscript and then Kaspa script.

Argent source -> generated Silverscript -> Kaspa script

The analogy is async lowering into a state machine. The developer writes the compact source form. The compiler expands it into the mechanical runtime representation: state fields, templates, routing checks, leader/delegate entrypoints, and successor validation.

Warning

Argent is early. Treat michaelsutton/argent as a design direction and prototype, not a production-stable API.

The problem it points at

Silverscript can express multi-contract covenant systems. The difficult part is keeping the route plumbing correct.

A contract family needs to know:

  • which roles exist;
  • which templates identify those roles;
  • which states can transition into which other states;
  • which peer inputs are allowed in the same transaction;
  • which outputs each entrypoint may authorize;
  • which hidden ABI fields must be preserved;
  • what launch proof an indexer or auditor needs.

That is too much to leave as copy-pasted convention forever.

Source model

Argent prototypes use app-level declarations for actor families.

app Stones {
    actor League;
    actor Player;
    actor StonesGame;
    actor StonesSettle;
}

The vocabulary is actor-oriented:

TermMeaning
appa closed actor/template family
statereusable covenant state layout
actora contract template with persistent state
entrya leader transition
delegatea non-leader verification path
consumespeer actors consumed in the same transaction
emitsnamed authorized outputs
becometerminal transition into successor actor state

The output should still be ordinary covenant code. Argent's job is to make the family-level intent explicit before lowering.

A multi-actor flow

Stones is a contract family, not a single contract.

flowchart TB
    classDef root fill:#eef6ff,stroke:#4b82c3,color:#172033
    classDef player fill:#eef9ef,stroke:#4d9f5b,color:#132016
    classDef game fill:#fff7e8,stroke:#c58b2a,color:#1f1b12

    L["League"]:::root
    P1["Player A"]:::player
    P2["Player B"]:::player
    G["StonesGame"]:::game
    S["StonesSettle"]:::game

    L -->|"register"| P1
    L -->|"register"| P2
    P1 -->|"start_game with P2"| G
    G -->|"play"| G
    G -->|"terminal"| S
    S -->|"settle"| P1
    S -->|"settle"| P2

The generated code has to preserve role identity across changing P2SH state. A shared covenant id can say "same family." It cannot by itself say "this input is a Player and that output is a Game." Template validation carries the role identity.

Hidden ABI state

Generated Silverscript may carry fields that are not business state.

template_league
template_player
template_stones_game
template_stones_settle

Those fields are route-safety state. Ordinary transitions preserve them so later outputs can be validated under the right templates.

That is the kind of data a developer should not hand-maintain in every transition if a compiler can preserve it.

Route commitments

Small apps can carry explicit template data. Larger apps probably need route commitments.

The pattern:

hidden state: route_root
entry witness: route leaf + Merkle branch + template prefix/suffix
generated check: leaf belongs to route_root
generated validation: validateOutputStateWithTemplate(...)

Commit early, expand late. Long-lived state carries a compact route commitment. The witness expands the route only when a transition needs it.

Same template and foreign template

When an output continues the same template as the active input, the generated code can use the simpler same-script path:

become self(next_state)
  -> validateOutputState(output_idx, next_state)

When an output becomes another actor, the code needs a foreign-template check:

become Player(next_player)
  -> validateOutputStateWithTemplate(output_idx, next_player, prefix, suffix, player_template)

Peer input reads are also template-sensitive. Covenant grouping proves family membership. It does not automatically prove actor role.

Leader and delegate defaults

A good default actor transition has one leader and small delegates.

sequenceDiagram
    participant L as Leader actor input
    participant D as Delegate actor input
    participant O as Authorized outputs

    L->>D: read peer state with template proof
    L->>O: validate named successors
    D->>L: verify leader and family/role

The leader reads peers and validates outputs. Delegates check that a valid leader is taking responsibility and that they are not authorizing stray outputs.

This default leaves room for ordinary fee/change inputs and multiple auth groups in the same transaction.

Launch proofs

Multi-contract apps need launch artifacts.

An indexer or auditor should be able to reconstruct:

  • the covenant id genesis material;
  • template preimages;
  • hidden ABI state;
  • route commitments;
  • current UTXOs and actor roles;
  • transaction-builder context.

This is one of the places Argent-like tooling becomes more than syntax. A generated app should come with the artifact needed to read it.

The compiler obligation

Generated code should eventually enforce:

  • declared covenant input layout;
  • declared authorized output layout;
  • hidden ABI state preservation;
  • typed foreign input checks;
  • same-template shortcuts where sound;
  • route membership checks;
  • successor state validation;
  • no transition into an undeclared output route.

Everything else should be ordinary app policy that a human can review.

How to use Argent today

Use Argent as a design lens.

It helps when:

  • one contract is not enough;
  • the app has distinct roles;
  • route safety is part of correctness;
  • launch proofs are needed for readers or auditors;
  • transaction builders become part of the protocol surface.

For production covenant work today, start in Silverscript. Borrow Argent's way of thinking about roles, routes, and generated lowering.

Use Decision Guide when deciding whether a multi-contract covenant family is still the right architecture, or whether the app has crossed into based-app territory.