.001 · Manual · v0.1.0-alpha

Verax program reference.

Verax is a Solana program plus a thin TypeScript SDK. This page documents the on-chain instructions, the account layouts, the trust-to-cap formula, and the deployment status.

.002 · Primitives

Eight primitives.

01
Reserve

Single program-derived address holds capital under your authority. Seeds: ["reserve", authority]. The PDA has no private key; only the program can move funds.

02
Lane

Per-agent sub-account derived as ["lane", reserve, handle]. Holds: trust score (bps), base daily cap (lamports), spent window, runs, paused flag.

03
Trust Score

u16 basis points (0–10000). Initialised at 5000 = 0.50. Updated by attest(deltaBps). Clamped to [50, 9900].

04
Adaptive Caps

effective_cap = base × mult(trust_bps). The multiplier is a piecewise-linear sigmoid approximation — verified inside settle, atomic revert on overflow.

05
Roster

Off-chain in v0.1. Planned: on-chain allowlist with mutate-by-authority and mutate-by-quorum modes.

06
Hours

Off-chain in v0.1. Planned: window enforcement using Solana clock (Clock::get) inside settle.

07
Replenish

Off-chain in v0.1. Planned: permissionless crank that refills lanes from reserve when balance < floor.

08
Quorum

Off-chain in v0.1. Planned: m-of-n proposals, automatically required when amount > k(trust).

.003 · Trust model

Cap formula.

Trust is stored as u16 basis points in [50, 9900]. The on-chain settle instruction multiplies the lane's base daily cap by a piecewise-linear approximation of a sigmoid centred at trust=0.50. Misbehaviour shrinks the cap fast; earned trust grows it gently and asymptotes near ×2.45.

fn cap_multiplier_bps(trust_bps: u16) -> u32 {
    let t = trust_bps as u32;
    match t {
        0..=2500    =>  500 + (t * 600) / 2500,                  // 0.05× → 0.11×
        2501..=5000 => 1100 + ((t - 2500) * 8900) / 2500,        // 0.11× → 1.00×
        5001..=8500 => 10_000 + ((t - 5000) * 11_000) / 3500,    // 1.00× → 2.10×
        _           => 21_000 + ((t.min(10_000) - 8500) * 3500) / 1500, // 2.10× → 2.45×
    }
}

fn effective_cap(base: u64, trust_bps: u16) -> u64 {
    ((base as u128) * (cap_multiplier_bps(trust_bps) as u128) / 10_000) as u64
}
.004 · Instructions

Five on-chain instructions.

create_reserveix #01
pub fn create_reserve(name: String) -> Result<()>
Accounts
  • authority (signer, mut)
  • reserve (init, pda)
  • system_program
Notes

Creates the reserve PDA under the signing wallet. One reserve per authority.

open_laneix #02
pub fn open_lane(handle: String, base_daily_cap_lamports: u64) -> Result<()>
Accounts
  • authority (signer, mut)
  • reserve (mut)
  • lane (init, pda)
  • system_program
Notes

Opens a per-agent lane. trust_bps starts at 5000.

attestix #03
pub fn attest(delta_bps: i32) -> Result<()>
Accounts
  • authority (signer)
  • reserve
  • lane (mut)
Notes

Mutates trust. v0.1: only authority. v0.2: signed attestations from approved attestors.

set_pausedix #04
pub fn set_paused(paused: bool) -> Result<()>
Accounts
  • authority (signer)
  • reserve
  • lane (mut)
Notes

Pause/resume a lane. Paused lanes reject settle.

settleix #05
pub fn settle(amount_lamports: u64) -> Result<()>
Accounts
  • authority (signer)
  • reserve (mut, PDA signer)
  • lane (mut)
  • recipient (mut)
  • system_program
Notes

Atomic: checks pause + cap, transfers from reserve PDA via CPI, updates lane.spent_window.

.005 · Account layouts

What's stored on chain.

Reserve
authority   : Pubkey
name        : String  (max 32)
lane_count  : u32
created_at  : i64
bump        : u8
seeds       : ["reserve", authority]
Lane
reserve         : Pubkey
handle          : String  (max 32)
base_daily_cap  : u64     (lamports)
trust_bps       : u16     (0..10000)
spent_window    : u64
window_start    : i64
runs            : u64
paused          : bool
bump            : u8
seeds           : ["lane", reserve, handle]
.006 · Use it

Quickstart.

  1. 01Open the console and connect Phantom or Solflare. Switch the wallet to Devnet.
  2. 02Use the wallet dropdown → Request 1 devnet SOL if you have nothing.
  3. 03In the Your reserve panel, click Create reserve — one signature.
  4. 04Open a lane (handle + base cap in SOL), top the reserve up, and try attest +200 / −200 bps to watch the cap move.
  5. 05Click settle ↗ to send SOL out of the reserve PDA through the program.
SDK reference →