Integrate Raven (customer stranger path)
One coherent path for a new integrator: obtain evidence, supply your own pinned trustedKeys, call verifyReceiptV1ForSubject with the exact expected subject, keep axes separate, and apply your policy. Raven never authorizes an action.
1. Obtain
Primary customer path: POST /receipt/v1 with your API key. Returns a signed receipt-v1 deliverable. POST /verify is legacy official-attestation v2 compatibility only.
- Primary test vector: /receipt-v1-test-vector.json
- Legacy v2 vector (explicitly not receipt-v1): /receipt-test-vector.json
- Recipe: security.html · policy: decision-policy.html
2. Package status (public truth)
- raven-receipt-verifier - ratified name; unpublished (npm 404). No public registry command yet.
- plugin-raven-verify@0.3.1 - installable ElizaOS adapter only. Consequential use requires independently supplied trusted keys; current fallback trusts same-host /pubkey when RAVEN_TRUSTED_KEYS is absent - do not rely on that discovery path as a trust root.
- raven-verify-js@0.1.0 - DEPRECATED, unsuitable for trust decisions.
- raven-verify-mcp - unsigned local/developer preview; not a signed receipt-v1 deliverable.
3. Pin (trust decision)
Supply Ed25519 key bytes yourself as trustedKeys (caller-controlled pin array). Cross-check site footer, repos, and GET /pubkey. /pubkey is discovery only, never a trust root. Never wire trustedKeys from fetch("/pubkey").
4. Verify receipt-v1 axes (real verifier shape)
Call verifyReceiptV1ForSubject(receipt, expectedSubject, options). Keep answers separate — never collapse into Raven authorization:
- valid — integrity/signature
- keyTrusted — caller-pin match
- stale — freshness (!stale required)
- subjectMatches === true — exact expected subject (chain + mintAddress + tokenProgramAddress)
- rulesStatus === "supported_valid" — exact string (not "ok", not a boolean)
5. Legacy v2
Legacy official-attestation v2 uses POST /verify, domain raven-official-attestation, and fields like verdict/replayHash/officialAttestationHash. Vector: /receipt-test-vector.json (family legacy-official-attestation-v2). Not for receipt-v1 verifiers. receipt-v1 is the current customer path; legacy v2 is compatibility only — not both current.
6. MCP
Local MCP (npx raven-verify-mcp) is unsigned developer preview — not a signed receipt-v1 deliverable. Use hosted POST /receipt/v1 for signed evidence.
7. Real verifier example
Timestamps must be ISO-8601 with Z (or an explicit offset). Never unzoned local times. Caller supplies the pin; do not invent a one-boolean Raven gate.
import { verifyReceiptV1ForSubject } from "raven-receipt-verifier";
// Caller-controlled pin (independently obtained). NOT fetch("/pubkey").
const trustedKeys = [
process.env.RAVEN_PINNED_PUBKEY
// e.g. "MCowBQYDK2VwAyEASGJt4Ilx2Z6g0BVC1VQIfaUcV0nr8WB1J45/8vfje6w="
];
const receipt = await postReceiptV1({ mintAddress, tokenProgramAddress });
const result = verifyReceiptV1ForSubject(
receipt,
{
chain: "solana-mainnet",
mintAddress,
tokenProgramAddress, // all three required
},
{ now: new Date(), trustedKeys },
);
// CUSTOMER POLICY (not a Raven verdict / pass / safe / approved):
const proceed =
result.valid &&
result.keyTrusted &&
!result.stale &&
result.subjectMatches === true &&
result.rulesStatus === "supported_valid";
CUSTOMER POLICY is your authorization gate over the five independent axes — not Raven saying pass/safe/verified. Axes stay separate: never gate on valid alone, never substitute verdict === "pass", never drop subjectMatches / token-program binding / rulesStatus === "supported_valid".