Attestations
Attestations let agents prove claims about their memories to other agents without revealing the actual content. zkStash signs the claim with Ed25519, enabling local verification.
For conceptual overview and use cases, see Attestations Concepts.
createAttestation()
Request a signed attestation from zkStash:
const result = await client.createAttestation({
claim: "has_memories_matching",
query: "cooking recipes",
filters: { agentId: "recipe-bot", kind: "Recipe" },
expiresIn: "24h",
});
console.log(result.attestation.result.satisfied); // true
console.log(result.attestation.result.matchCount); // 47
console.log(result.signature); // "0x..."Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
claim | string | Yes | Claim type (see below) |
query | string | Conditional | Search query (for has_memories_matching) |
filters | object | No | Filter by agentId, kind, tags |
threshold | number | Conditional | Minimum count (for memory_count_gte) |
schemaName | string | Conditional | Schema name (for has_schema) |
expiresIn | string | No | Validity duration (default: "24h") |
Claim Types
| Claim | Description | Required Params |
|---|---|---|
has_memories_matching | Memories exist matching query | query |
memory_count_gte | At least N memories exist | threshold |
has_schema | Schema is registered | schemaName |
Response
{
attestation: {
claim: "has_memories_matching",
params: { query: "...", filters: {...} },
result: {
satisfied: boolean, // Did claim pass?
matchCount?: number, // Matches found
namespace: string // Hashed userId
},
issuedAt: number, // Unix timestamp
expiresAt: number, // Expiry timestamp
issuer: "zkstash.ai"
},
signature: string, // Ed25519 signature
publicKey: string // For verification
}Examples
// Prove expertise in a domain
await client.createAttestation({
claim: "has_memories_matching",
query: "machine learning research",
filters: { kind: "ResearchPaper" },
});
// Prove minimum knowledge base size
await client.createAttestation({
claim: "memory_count_gte",
threshold: 100,
filters: { agentId: "researcher" },
});
// Prove schema capability
await client.createAttestation({
claim: "has_schema",
schemaName: "UserProfile",
});verifyAttestation()
Verify a received attestation locally—no API call, no cost:
const { valid, reason } = await client.verifyAttestation(
receivedAttestation.attestation,
receivedAttestation.signature
);
if (valid) {
const { satisfied, matchCount } = receivedAttestation.attestation.result;
console.log(`Verified: satisfied=${satisfied}, count=${matchCount}`);
} else {
console.log(`Invalid: ${reason}`);
}Parameters
| Parameter | Type | Description |
|---|---|---|
attestation | Attestation | The attestation object to verify |
signature | string | The Ed25519 signature |
Response
{
valid: boolean, // Signature valid and not expired?
reason: string | null // "invalid_signature" | "attestation_expired" | null
}How It Works
- SDK fetches zkStash’s public key from
/.well-known/zkstash-keys.json(cached) - Verifies the Ed25519 signature locally
- Checks
expiresAt > now
Source Attestations
When searching with grants, responses include automatic provenance proofs:
const results = await client.searchMemories(
{ query: "findings", filters: { agentId: "researcher" } },
{ grants: [grantFromAgentA] }
);
// results.sourceAttestations is keyed by grantor address
if (results.sourceAttestations) {
for (const [grantor, proof] of Object.entries(results.sourceAttestations)) {
const { valid } = await client.verifyAttestation(
proof.attestation,
proof.signature
);
console.log(`${grantor}: ${valid ? "verified" : "unverified"}`);
}
}Source attestations prove memories came from the claimed grantor’s namespace.
Pricing
| Operation | Cost |
|---|---|
createAttestation() | 3 credits |
verifyAttestation() | Free |
Last updated on