Skip to content
LogoLogo

Quickstart

This walk-through writes the corridor policy from the specification: an amount cap when a payment is initiated and a country deny-list when it is accepted. It targets the toolchain as specified; commands and output will be pinned once the CLI ships.

Enter the pinned toolchain

The repository pins nargo, bb, Foundry, and pnpm in flake.nix. Every verification key hash recorded in a manifest is reproducible by anyone using the same pin.

nix develop

Create a policy crate

A policy is a Noir library crate. It never contains a main.

weld init corridor
cd corridor

Write the rule

// src/lib.nr
use weld::{Rule, Ctx, Initiate, Accept, Reject, Verdict, Attest};
use weld::schema::v1::*;
 
#[weld::params]
struct Params {
    cap: u128,
    blocked_countries: [Field; 8],
}
 
#[weld::policy(params = Params)]
struct Corridor;
 
impl Rule<Params> for Corridor {
    fn on_initiate(p: Params, ctx: Ctx<Initiate>) -> (Verdict, Attest) {
        let note = ctx.recipient_note();
        let v = Verdict::require(note.amount <= p.cap, "corridor/over-cap");
        (v, Attest::none())
    }
 
    fn on_accept(p: Params, ctx: Ctx<Accept>) -> (Verdict, Attest) {
        let record = ctx.payload().record();
        let mut v = Verdict::ok();
        for c in p.blocked_countries {
            v = v.and(Verdict::require(record.beneficiary_country() != c, "corridor/blocked"));
        }
        (v, Attest::none())
    }
    // on_reject: the default implementation permits.
}

Three things to notice. Every accessor returns a value already welded to the context root. The rule returns a Verdict rather than asserting, so it composes with combinators. And ctx.inputs() would compile in on_initiate but not in on_accept, because the sender's private region is unknowable at that phase.

Build

weld build generates three thin bin packages, one per phase, compiles them, writes verification keys, and emits weld.json.

weld build

The manifest records the toolchain pin, per-phase VK hashes and gate counts, the params schema, and every assert id.

Test against the golden world

weld test

This runs five lints. Satisfiability fails the build if any phase cannot solve on a golden payment shape. Weld coverage mutates every witnessed leaf and requires a weld/… assert to fail. Sensitivity warns when no mutation of a read leaf can make the rule fail. Negatives check the catalog rules' generated violations. Budget checks gates against weld.toml.

Set parameters and register

Parameters are salted and committed. Changing them never changes a verification key.

weld params set --cap 500e18
weld register

Both commands sign with the institution's messaging key through a signer abstraction, so the key can live in an HSM.

Next steps