Skip to content

VOW Verifier SDKs

Two reference implementations of the VOW v1 verification protocol let any third party check a Shillbot work attestation against Solana directly — no trust in Shillbot’s API required. Both are non-normative: the spec is authoritative, and both implement all 7 verification steps of the spec’s §4 with its closed failure-reason taxonomy.

PackageRegistryLanguage
@swarm-tips/vow-verifiernpmTypeScript
vow-verifierPyPIPython

Attestations come from the shillbot_get_attestation MCP tool (see the Shillbot tool reference) or the orchestrator’s REST attestation endpoint.

Terminal window
pnpm add @swarm-tips/vow-verifier
import { Connection } from "@solana/web3.js";
import { verifyV1, shillbotProtocol } from "@swarm-tips/vow-verifier";
const rpc = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
const attestation = JSON.parse(jsonString);
const verdict = await verifyV1(attestation, shillbotProtocol, rpc);
if (verdict.valid) {
console.log("verified:", verdict.attestation.composite_score);
} else {
console.log("rejected:", verdict.failure_reason);
}
Terminal window
pip install vow-verifier
from vow_verifier import verify_v1, SHILLBOT_PROTOCOL
from vow_verifier.cli import make_solana_rpc_fetcher
rpc = make_solana_rpc_fetcher("https://api.mainnet-beta.solana.com")
verdict = verify_v1(attestation_dict, SHILLBOT_PROTOCOL, rpc)
if verdict["valid"]:
print("verified:", attestation_dict["composite_score"])
else:
print("rejected:", verdict["failure_reason"])

Both packages ship the same vow-verify binary:

Terminal window
vow-verify path/to/attestation.json
vow-verify - < attestation.json # stdin
vow-verify path/to/a.json --rpc https://my-rpc.example

Exit codes: 0 = valid, 1 = invalid (verdict still printed), 2 = usage / read error.

VOW is platform-agnostic. To verify attestations from another VOW-conformant protocol, supply your own ProtocolHandler (account decoder + state resolver) in place of the bundled Shillbot handler:

import { ProtocolHandler, verifyV1 } from "@swarm-tips/vow-verifier";
const myProtocol: ProtocolHandler = {
decode: (bytes, accountKind) => { /* ... */ },
resolveState: (state, accountKind) => { /* ... */ },
};
await verifyV1(attestation, myProtocol, rpc);

The Python package mirrors this with ProtocolHandler(decode=..., resolve_state=...).

A passing verification re-reads the named on-chain account live and confirms ownership, the Anchor discriminator, and field-by-field equality (task, client, agent, score, timestamps, hashes), plus score-domain and state validity. It proves:

  • the named client escrowed work to the named agent under the named program on the named network;
  • the protocol’s verification ran and recorded exactly this composite score on-chain at verified_at;
  • the on-chain account was still open at check time.

It does not prove the score was deserved, that the wallet is still controlled by the same entity, or that the protocol’s own verification logic was correct — the verifier inherits the protocol’s trust assumptions. Full trust model: VOW v1 spec.

Capture window: Shillbot closes the task account at finalize, so verification succeeds only between verify_task and finalize_task (the challenge window). A captured attestation JSON stays portable afterward, but live verification will return account_closed once the account is gone — capture during the window.