W3O1 v1-v3 · technical reference

Specification

Technical reference for on-chain proof of who won: committed W3O1 rules, replay semantics, operator security, and public API surface.

W3O1 v1-v3 solana devnet SHA-256 ed25519 deterministic replay
01

Rules

VRE commits binary W3O1 artifacts on-chain. The public input object is compiled into one of three currently active artifact families:

FieldTypeMeaning
W3O1 v1binaryWeighted-random single-winner artifacts.
W3O1 v2binaryWeighted-random multi-winner artifacts with ordered outcome_ids.
W3O1 v3binaryNative formula artifacts: weighted_random, rank_desc, rank_asc, first_n, closest_to.
runtime_idbytes16 / hexCommitted runtime identifier emitted in replay output.
compiled_artifact_hashsha256 hexCanonical hash of the compiled bytes bound before resolution.
outcome_idsstring[]Selected outputs in deterministic order. Single-winner flows also expose outcome_id.
02

Input Schema

The human-facing config stays JSON, but the serialized on-chain contract is W3O1. Public API inputs differ by formula and artifact version.

formula-config.json
{ "formula": "closest_to", "target": 22450, "winners_count": 2, "participants": [ { "id": "alice", "score": 22300 }, { "id": "bob", "score": 22610 }, { "id": "carol", "score": 22480 } ] }
03

Determinism

The kernel is a pure mapping f(seed, artifact) → outcome_ids. Three guarantees:

  • Referential transparency. Same inputs always yield the same output, forever.
  • No hidden state. Replay reads only public RPC data plus the committed W3O1 bytes.
  • Platform-neutral. Browser, Node, and on-chain logic agree on weights, scores, stable order, and targets.

W3O1 v3 adds deterministic formulas without changing replay semantics: the verifier still reconstructs the exact committed bytes and compares replay output with the resolved transaction.

04

Replay Process

Given a transaction signature, the verifier performs:

  1. Fetch the transaction from any Solana RPC endpoint.
  2. Confirm it invokes the VRE program and is a resolve instruction.
  3. Extract runtime_id, compiled_artifact_hash, resolution seed, and claimed outputs.
  4. Fetch the referenced artifact-binding history; confirm the artifact was committed before resolution.
  5. Re-hash the compiled W3O1 bytes and confirm they match the committed artifact hash.
  6. Run f(seed, artifact) locally; compare the replayed outputs with the on-chain record.

For W3O1 v3 responses, replay additionally exposes resolution_formula, target, per-outcome score, and stable order. If all checks pass: MATCH / OK.

05

Canonical Program

VRE operates a canonical Solana program on devnet. Any developer can integrate against this deployed program without deploying a separate instance.

Program ID
9tEramtR21bLBHvXqa4sofVBPa1ZBho4WzhCkCimFE1F
Cluster
Solana devnet (mainnet pending)
Upgrade authority
Squads vault PDA 8o5a6hj22sEsmpsYTN8aM4GUwKGkR1YXKsgYQdiVkbgA
Multisig
7jtA1fkZNrg7ZntGQtpXtAi9JxZEzgRjGRuGvdScZQqQ · Squads

ProgramConfig

Global configuration stored in a PDA at seeds ["outcome_program_config"]. ProgramConfig admin is separate from the program upgrade authority.

FieldTypeDescription
adminPubkeyAuthority allowed to update config. Current devnet value: Swig actor wallet E8wB17KxBi89Noz74eypjbcrAJXhmPeA7e7oYHZSbjzf.
allow_unreviewed_bindingboolWhether unreviewed artifacts can be bound.
fee_lamportsu64Protocol fee per resolveOutcome call. Current devnet value: 0.
treasuryPubkeyRecipient of protocol fees when fee_lamports > 0. Current devnet value: ESjxDsMvG2SkPpK1FdcD6Lce4RUfMM8Bvg6sfFBUsXkT.

Operator Security

VRE separates two security concerns: who can upgrade the program and who can operate it.

LayerMechanismAddress
Program upgradesSquads governance plus vault PDA execution — proposals are approved via multisig, but the live program authority is the vault address.8o5a6hj22sEsmpsYTN8aM4GUwKGkR1YXKsgYQdiVkbgA
Operator signingSwig smart wallet — delegated key scoped to VRE program with daily SOL spending cap. Master keypair kept offline.Actor: E8wB17KxBi89Noz74eypjbcrAJXhmPeA7e7oYHZSbjzf

Swig — why it matters

The canonical operator runs as a Swig smart wallet actor. The hot delegate key is scoped to the VRE program only and carries a daily SOL spending cap — a compromised delegate cannot drain the treasury or invoke unrelated programs. The master keypair that controls the Swig wallet is kept offline. This means every live raffle on /play is signed by a key that has no broader permissions than running VRE.

Live Governance Upgrade

The upgrade authority is not just configured — it has been exercised on-chain. VRE was upgraded via the full Squads proposal flow on devnet: create → approve → execute.

StepTransaction
1. Vault tx create48de7Cy…
2. Proposal create2dqUG4E…
3. Proposal approve5AuwR1b…
4. Execute (upgrade)2AKZBt5…

Deployed at slot 459318657. Upgrade authority remained 8o5a6hj22sEsmpsYTN8aM4GUwKGkR1YXKsgYQdiVkbgA throughout — the Squads vault PDA, not any individual keypair. Evidence artifact: artifacts/squads_upgrade_evidence.json.

Protocol Fee

Each resolveOutcome call may collect a protocol fee from the calling operator. The transfer happens before resolution; if the operator wallet cannot pay, the transaction fails and no outcome is recorded.

Current devnet fee: 0 lamports. The value is configurable through ProgramConfig.fee_lamports by the program admin without a program upgrade.

Verification is always free: /api/replay, SDK verify, and verify.html do not require a wallet. Large platforms can deploy a dedicated instance under a partner agreement. Contact us →

06

Output

Every vre verify call returns a stable JSON shape. winner / replayed_winner carry the single selected address; outcome_ids carries the ordered list when outputs > 1.

response.json — single winner
{ "status": "MATCH", "code": "OK", "signature": "5KJp…9vW2", "cluster": "devnet", "commit_slot": 455663125, "resolve_slot": 455693113, "artifact_hash": "0x14f195…b4d8d", "winner": "7FHkp…3GnV", "replayed_winner": "7FHkp…3GnV", "elapsed_ms": 248 }
response.json — multi-winner (outputs: 3)
{ "status": "MATCH", "code": "OK", "signature": "9XAr…mQ3k", "winner": "7FHkp…3GnV", "outcome_ids": ["7FHkp…3GnV", "AkB2…vR9t", "9PLm…jJ1w"], "replayed_winner": "7FHkp…3GnV", "elapsed_ms": 261 }
07

Verification Reason Codes

Every verification returns a specific reason code. MATCH always carries OK. Any MISMATCH carries one of the error codes below.

CodeMeaning
OKAll transaction, account, artifact, randomness, outcome, and effects checks passed.
ERR_TX_NOT_FOUND_OR_NO_LOGSTransaction not found on RPC or its logs are unavailable.
ERR_PROGRAM_ID_MISMATCHThe expected program ID was not invoked, or the event came from a different program.
ERR_EVENT_DISCRIMINATOR_MISMATCHProgram data was present, but it did not match the expected outcome event format.
ERR_EVENT_NOT_FOUND_FOR_PROGRAMNo resolution event was found in logs for the requested program ID.
ERR_ARTIFACT_CHUNK_MISSINGOne or more committed artifact chunks are missing, unreadable, or inconsistent.
ERR_OUTCOME_CONFIG_NOT_FOUNDThe derived outcome config account is missing or cannot be decoded.
ERR_RESOLUTION_ACCOUNT_NOT_FOUNDThe derived outcome resolution account is missing or cannot be decoded.
ERR_ARTIFACT_HEADER_NOT_FOUNDThe approved artifact header account is missing or cannot be decoded.
ERR_CONFIG_HASH_MISMATCHConfig hash does not match the on-chain outcome config account.
ERR_RESOLUTION_HASH_MISMATCHResolution hash does not match the on-chain resolution account or event identity.
ERR_ARTIFACT_HASH_MISMATCHCompiled artifact hash does not match the committed on-chain artifact value.
ERR_ARTIFACT_NOT_FINALIZEDThe approved artifact account exists but was not finalized before verification.
ERR_ARTIFACT_STATUS_INVALIDThe artifact status does not allow binding under current program config.
ERR_RANDOMNESS_MISMATCHInput randomness does not match the recorded on-chain value.
ERR_INPUT_MISMATCHInput lamports differ between the event, account, and replay input.
ERR_OUTPUT_MISMATCHReplayed output does not match the recorded output value.
ERR_OUTCOME_ID_MISMATCHReplayed outcome id does not match the recorded outcome id.
ERR_EFFECTS_DIGEST_MISMATCHEffects count or effects digest does not match.
ERR_REPLAY_UNHANDLEDInternal error or unsupported artifact shape during replay.

Full reference on GitHub →

08

Metaplex Agent Registry

VRE is registered in the Metaplex Agent Registry as a verification service. Other agents and dApps can discover VRE through the registry and call its endpoints to verify outcomes without trusting the operator.

Agent Identity

NameValue
NameVRE Outcome Verification Agent
Networksolana-devnet
Asset addressC3qM2VVxR5dyjzqEvv9qHaaUDfTDneEaJCMTKV9bxQLX
Mint tx429YX7c7…jj ↗
Registrationapi.metaplex.com ↗

Exposed services

TypeEndpointPurpose
web/verifyBrowser-based outcome verifier
replay-api/api/replayProgrammatic verification — call from any agent
web/playLive demo with active devnet signatures

Agent-to-agent use

Any agent that selects a winner, assigns a task, or picks a DAO proposal can call POST /api/replay with the resolve transaction signature. VRE replays the outcome from public RPC and returns MATCH / OK — or an error code if the result was tampered with. No oracle, no operator trust required.

# Any agent verifies a VRE outcome curl -s https://verifiableoutcome.online/api/replay \ -H "content-type: application/json" \ -d '{"signature":"<resolve_tx_sig>","programId":"9tEramtR21bLBHvXqa4sofVBPa1ZBho4WzhCkCimFE1F"}' → { "ok": true, "replay": { "verification_result": "MATCH", "verification_reason": "OK", … } }

Partner API access

Partner discovery endpoints GET /api/resolutions and GET /api/participant are not part of the public SDK surface. They require a partner-issued API key in x-api-key: vresk_... and are provisioned during partner onboarding.

Missing or unknown keys return 401 Unauthorized. If partner config is absent on the host, the endpoints fail closed with 503 Partner API not configured.

09

Sybil-Proof Participants

VRE can optionally require a World ID 4.0 proof before a live raffle is sent on-chain. This blocks one human from entering the same action repeatedly through many wallets, while keeping the core raffle, replay semantics, and blessed signatures unchanged.

Flow

  1. User connects Phantom on /play.html and optionally enables Require World ID.
  2. Frontend fetches POST /api/world-id/rp-context and starts a World ID 4.0 request through IDKit with RP signatures.
  3. Backend forwards the full IDKit result to POST https://developer.world.org/api/v4/verify/{rp_id}.
  4. Verified nullifier is reserved in-memory before /api/live-raffle executes and is rolled back if the raffle fails before completion.
  5. If World ID is not configured, the existing live raffle path still works without the optional toggle.
Env varMeaning
WORLD_APP_IDWorld app identifier (app_...) returned by the Developer Portal.
WORLD_RP_IDRelying-party identifier (rp_...) used by the v4 verify endpoint.
WORLD_RP_SIGNING_KEYServer-only RP signing key used to mint short-lived RP signatures.
WORLD_ACTION_IDAction scope for the one-human-per-entry flow. Default: vre-raffle-entry.
WORLD_ENVIRONMENTstaging for simulator/testing or production for real World App traffic.

Evidence Artifact

Public reviewer evidence for this optional integration lives in artifacts/world_id_evidence.json and records the configured app/RP IDs, action, environment, and a staging nullifier placeholder for the first simulator-backed proof.

Phantom — "Did I Win?"

Phantom is supported on the /verify page for a read-only wallet check. After connecting, the page compares the connected address against outcome_ids in the resolved artifact and shows one of three states: You won, In the draw — not selected, or Not in this draw. No transaction signing is required — Phantom is used for address read only.

10

Live Raffle API

POST /api/live-raffle is the single-call path for the play.html demo. The server commits, resolves, and returns a blessed transaction signature — no operator wallet required from the caller.

FieldTypeDescription
addressstringCaller’s Solana address. Entered in the draw pool.
requireWorldIdbool?If true, a valid World ID v4 proof is required (see §9). Default: false.
worldIdobject?Full IDKit proof payload. Required when requireWorldId is true.
request / response
# Enter the live draw pool curl -s https://verifiableoutcome.online/api/live-raffle \ -H "content-type: application/json" \ -d '{"address":"<your-wallet>"}' → { "ok": true, "sig": "5KJp…9vW2", "outcome": "<winner-address>", "outcome_id": "<winner-address>", "outcome_ids": ["<w1>", "<w2>", …] }

Rate limited: one call per IP per 60 seconds. The returned sig is immediately replayable on /verify or via POST /api/replay.

11

SDK

verifiable-outcome-sdk is the canonical TypeScript library for building and verifying outcomes. It targets Node ≥ 18 and any modern bundler.

install

npm install verifiable-outcome-sdk # v0.3.0

build + verify

import { buildArtifact, verifyOutcome } from "verifiable-outcome-sdk"; // Compile a ruleset into an artifact hash const artifact = await buildArtifact({ version: "1.0", mode: "raffle", participants: ["Alice", "Bob", "Carol"], weights: [1, 1, 1], }); // → { artifact_hash: "0x…", … } // Verify a resolved transaction const result = await verifyOutcome({ signature: "5KJp…9vW2", programId: "9tEramtR21bLBHvXqa4sofVBPa1ZBho4WzhCkCimFE1F", }); // → { status: "MATCH", code: "OK", winner: "…", … }

Both functions are pure — no on-chain writes. buildArtifact runs the same deterministic kernel used by the Solana program. verifyOutcome fetches the transaction from any public RPC and replays it locally. See build.html for the full operator integration guide.

12

Partner API

Two discovery endpoints are gated behind a partner-issued API key. They allow external platforms to query resolution history and check participant outcomes without running their own indexer.

EndpointMethodDescription
GET /api/resolutionsGETReturns the N most recent resolved outcomes on the canonical program. Includes signature, outcome_id, outcome_ids, participants_count, artifact_hash, commit_slot, resolve_slot.
GET /api/participantGETReturns all resolutions where ?address=<wallet> appears in outcome_ids. Useful for wallet-level "did I ever win?" lookups.

authentication

# All partner endpoints require x-api-key header curl https://verifiableoutcome.online/api/resolutions \ -H "x-api-key: vresk_<32-hex-chars>" # Without a key: 401 Unauthorized # Config absent on host: 503 Partner API not configured
Key formatStorageProvisioning
vresk_ prefix + 32 hex charsServer-side config/partners.json (not committed). Never sent to the client.Issued during partner onboarding. Contact us →

Partner API endpoints are distinct from the public SDK surface (/api/replay, /api/live-raffle). The public endpoints are rate-limited but require no key. Partner endpoints carry higher rate limits and return richer indexer data suitable for dashboards and integrations.

Sybil detection data feed: /api/resolutions and /api/participant were built as a structured data source for sybil-detection models. A model can observe which wallets appear repeatedly across participant lists, correlate on-chain behavior with resolution outcomes, and use commit-slot vs resolution-slot timing as a signal. These endpoints are the integration point for Proof of Human Network — feeding high-quality on-chain participation data into their LLM-based sybil classifier.

POST /api/partner/draw

Submit a formula-driven participant list and receive a verifiable on-chain transaction signature. The draw runs against the canonical devnet program using the operator wallet. Requires "draw_enabled": true in the partner config entry.

FieldTypeRequiredDescription
formulastringYesOne of weighted_random, rank_desc, rank_asc, first_n, closest_to.
participantsobject[]Yes2–100 unique participant objects. Each item must contain id; score and weight depend on the selected formula.
winners_countintegerNoNumber of winners to select (1–10). Defaults to 1. Must be ≤ participants.length.
targetintegerNo*Required only for closest_to. Signed safe integer, usually a pre-scaled score target.
labelstringNoHuman-readable label for the draw (max 80 chars). Auto-generated if omitted.
use_casestringNoOne of raffle, airdrop, competition. Informational only.
Response fieldTypeDescription
okbooleantrue on success.
signaturestringSolana transaction signature of the resolution tx.
outcome_idstringPrimary selected participant id.
outcome_idsstring[]All selected participant ids (length = winners_count).
replay_urlstringPublic verifier URL for independent replay.
artifact_slotnumber | nullSlot when the artifact was committed on-chain (null if lookup failed).
resolution_slotnumber | nullSlot when the resolution tx landed (null if lookup failed).

Rate limit: one draw per partner key per 60 seconds. Exceeding the limit returns HTTP 429 with retry_after_ms.

HTTP statusMeaning
200Draw completed successfully.
400Validation error (bad formula, bad participant ids, duplicates, invalid score / weight / target, invalid winners_count or use_case).
401Missing or unknown API key.
403Valid key but draw_enabled is not true for this partner.
429Rate limit exceeded; retry after 60 s.
504Devnet timeout; retry.
POST /api/partner/draw
curl -s -X POST https://verifiableoutcome.online/api/partner/draw \ -H "Content-Type: application/json" \ -H "x-api-key: vresk_YOUR_KEY" \ -d '{"formula":"closest_to","target":22450,"participants":[{"id":"alice","score":22449},{"id":"bob","score":22460},{"id":"carol","score":22451}],"winners_count":1,"label":"Price Prediction"}' # 200 response: { "ok": true, "signature": "5xYz...", "outcome_id": "carol", "outcome_ids": ["carol"], "replay_url": "https://verifiableoutcome.online/verify?sig=5xYz...", "artifact_slot": 340123456, "resolution_slot": 340123512 }
13

W3O1 v3 Native Formula Layout

Formula draws are committed natively inside the artifact bytes. Old v1/v2 artifacts stay valid; v3 adds explicit formula metadata, signed scores, stable input order, and optional target support for closest_to.

Header fieldTypeDescription
magicbytes[4]Always "W3O1".
format_versionu163 for formula-native artifacts.
min_input_lamports / max_input_lamportsu64 / u64Replay and on-chain input bounds, unchanged from v1/v2.
outcome_count / effect_countu16 / u16Outcome directory and effect directory lengths.
winners_countu16Number of winners to select.
formula_codeu81=weighted_random, 2=rank_desc, 3=rank_asc, 4=first_n, 5=closest_to.
reservedbytes[5]Must be zero.
target_scorei64Used by closest_to; 0 otherwise.
Outcome fieldTypeDescription
outcome_id_lenu8Length of the canonical printable-ASCII id.
outcome_idbytes[64]Participant id padded with zeroes.
weightu32Weighted-random weight. For deterministic formulas current API writes 1.
scorei64Signed score for ranking / closest formulas; 0 when unused.
orderu16Stable input order for first_n and all deterministic tie-breaks.
first_effect_index / effect_countu16 / u16Effect slice for this outcome.

Formula rules: rank_desc sorts by score desc, rank_asc by score asc, first_n by order asc, and closest_to by abs(score-target) asc. All deterministic ties break by order asc.

14

Use Cases & Integrations

Real-world patterns that map directly to W3O1 formulas. Each use case commits rules before resolution — anyone can replay from the transaction signature and confirm the outcome.

Use caseFormulaHow it works
Raffle / NFT drop weighted_random Each ticket holder is a participant with weight equal to their ticket count. The artifact commits weights before the draw — no backend can adjust probabilities after the list is published.
Trading competition rank_desc Participants are registered with their final PnL as score. Top-N are selected deterministically. Anyone verifies the leaderboard is correct.
Prediction market / oracle contest closest_to Participants submit predicted values. The target (e.g. actual price or temperature) is committed alongside scores. Winners are those closest to the target — provably, not just claimed.
Airdrop (first-come) first_n Participants are ordered by registration timestamp encoded in order. First N wallets receive the drop. Order is locked on-chain before snapshot.
Pack break / loot drop weighted_random Each slot in a card pack or loot pool is a weighted outcome. The full slot list and weights are committed before the break — viewers can verify no slot was swapped after the stream started.
Lowest-bid contest rank_asc Participants submit bids or scores; the lowest value wins. Scores are locked in the artifact — no late entries or score adjustments possible after commit.

Sponsor integrations

SponsorRoleIntegration
Squads Multisig Program upgrade authority held by Squads vault PDA — proposals approved via multisig, executed on-chain
Swig Operator Delegated operator key scoped to VRE program with daily SOL cap — master keypair kept offline
Metaplex Agent Registry Agent VRE registered as verifiable-outcome agent — discoverable by other agents and dApps
World ID Sybil resistance World ID 4.0 proof gating — one wallet per human before raffle entry (pending World App approval)

Live integrations

ProjectUse caseIntegration
Proof of Human Sybil detection data feed /api/resolutions + /api/participant — outcome data feeds into PoH LLM sybil classifier
NanoCommando Game leaderboard verification Partner Draw API — rank_desc pre-commitment for GHOST tier leaderboard (planned post-hackathon)
GAS Grading Trading card giveaways & pack breaks Partner Draw API — weighted_random draws and slot allocation (planned post-hackathon)
01 Pilot Agent bounty payout verification Partner Draw API — pre-committed task criteria before payout selection (planned post-hackathon)
UZPROOF Sybil-filter + verifiable selection UZPROOF filters wallets → VRE selects winner on-chain — end-to-end sybil-proof draw (planned post-hackathon)
AlphaDex Trading competition leaderboard Partner Draw API — rank_desc leaderboard pre-commitment (planned post-hackathon)
Zaebis.xyz Price prediction contests Partner Draw API — closest_to outcomes resolved on-chain (planned post-hackathon)
BharatFeed Equities leaderboard Partner Draw API — rank_desc leaderboard resolution (planned post-hackathon)