Evidence Verification Guide
Schema: treasury-audit/2.5 + treasury-scenarios/1.2 · Independent 6-step verification
📦 Verifier Kit (Download)
verify_response.py verify_response.js Test Vector (Response) Test Vector (Request) Expected Hash RELEASE.json Release Signature py.sha256 js.sha256 response.sha256
Python: pip install ecdsa · Node.js: zero dependencies (built-in crypto)
1 Get a response
curl -s -X POST https://api.feedoracle.io/api/v2/risk/treasury-audit \
-H "Content-Type: application/json" \
-d '{"holdings":{"USDT":5000000,"USDC":3000000}}' \
-o response.json
Or use the static test vector for offline verification.
2 Remove /evidence + /manifest_id
Per hash_scope.exclude_paths: ["/evidence", "/manifest_id"], strip evidence and manifest_id keys.
body = {k: v for k, v in response.items() if k not in ("evidence", "manifest_id")}
3 JCS Canonicalize (RFC 8785)
Sort keys, no whitespace.
# Python
canon = json.dumps(body, sort_keys=True, separators=(",",":"))
// Node.js — recursive key sort
function jcs(obj) {
if (obj === null || typeof obj !== 'object') return JSON.stringify(obj);
if (Array.isArray(obj)) return '[' + obj.map(jcs).join(',') + ']';
return '{' + Object.keys(obj).sort()
.map(k => JSON.stringify(k) + ':' + jcs(obj[k])).join(',') + '}';
}
4 SHA-256 → must match evidence.content_hash.hex
computed = hashlib.sha256(canon.encode()).hexdigest() assert computed == response["evidence"]["content_hash"]["hex"]
If MATCH — the response body has not been tampered with.
5 Load public key from JWKS
curl -s https://feedoracle.io/.well-known/jwks.json
Select key matching evidence.key_id (feedoracle-prod-2026). Curve: secp256k1.
6 Verify ECDSA signature
Signature is raw r||s hex (64 bytes) over the SHA-256 digest from Step 4.
signed_over.field: /evidence/content_hash/hex
# Python (pip install ecdsa)
vk.verify_digest(sig_bytes, digest)
// Node.js (built-in crypto)
crypto.verify('sha256', Buffer.from(canon), pubKey, derSig)
If SIGNATURE VALID — the response was produced by FeedOracle's signing key.
python3 verify_response.py test_response.json or
node verify_response.js test_response.jsonBoth produce HASH MATCH Yes + SIGNATURE VALID Yes. Works with both
/treasury-audit and /scenarios responses.
POST /api/v2/risk/treasury-audit (schema: treasury-audit/2.5)POST /api/v2/risk/treasury-audit/scenarios (schema: treasury-scenarios/1.2)Same evidence structure, same verification procedure, same signing key.
7 Verify the Verifier Kit (Supply Chain)
The entire kit is a signed release. Download and verify locally:
python3 verify_response.py --verify-release . node verify_response.js --verify-release .
This checks: manifest hash, ES256K signature via JWKS, and every file hash + size.
Result: ALL VERIFIED = the kit is exactly what FeedOracle published.