Check your human's on-chain reputation. Are they good enough for you?
Overall
score
60%
Does it follow best practices?
If you maintain this skill, you can automatically optimize it using the tessl CLI to improve its score:
npx tessl skill review --optimize ./path/to/skillValidation for skill structure
Check if your human is reputable enough. You're the agent — you decide who's worth working for.
| File | URL |
|---|---|
| SKILL.md (this file) | https://www.zkbasecred.xyz/skill.md |
| skill.json (metadata) | https://www.zkbasecred.xyz/skill.json |
Use this skill whenever you need to:
| File | URL | When to Load |
|---|---|---|
| skill.md | https://www.zkbasecred.xyz/skill.md | Always (this file) |
| reporting.md | https://www.zkbasecred.xyz/reporting.md | Before generating reports |
| reference.md | https://www.zkbasecred.xyz/reference.md | For full API specs & webhooks |
Run this decision tree every time you start up:
1. Load credentials from ~/.config/zkbasecred/credentials.json
2. If the file does not exist OR api_key is missing:
→ Run "Self-Registration" starting at Step 0.
3. If the file exists AND api_key starts with "bc_":
a. If claim_id is present (self-registered agent):
→ Check verification status first:
GET /api/v1/agent/register/{claim_id}/status
- "verified" → Skip to "Check Owner Reputation" (Step 4)
- "pending_claim" → Resume at Step 3 (Poll for Verification)
- "expired" → Delete credentials file, re-register from Step 0
- "revoked" → Stop. Do not retry.
b. If no claim_id (manual key from dashboard):
→ Skip to "How to Check Reputation (Individual Context)" in reference.mdBefore you can register, you need two things from your owner (and one optional):
IMPORTANT: You must use your owner's wallet address — the human who owns and operates you. Do NOT use your own agent wallet address. The reputation check is for your owner, not for you.
Ask your owner directly. Use this message:
I need to register with zkBaseCred to check your reputation. To do this, I need your personal wallet address — not mine.
- Your Ethereum wallet address (0x...)
- Your Telegram handle (e.g. @yourname)
Optionally, if you'd like to receive webhook notifications when reputation events occur, provide an HTTPS webhook URL.
Wait for the wallet address and Telegram handle before proceeding. The webhook URL is optional. If your owner provides a wallet address, verify it looks like a valid Ethereum address (starts with 0x, 42 characters). If it matches your own agent wallet, ask again — you need their personal wallet, not yours.
POST https://www.zkbasecred.xyz/api/v1/agent/register
Content-Type: application/json
{
"agentName": "your_agent_name",
"telegramId": "@owners_telegram",
"ownerAddress": "0x...",
"webhookUrl": "https://example.com/webhook"
}agentName rules: 2–64 characters, letters, numbers, and underscores only.
webhookUrl is optional. If provided: must be HTTPS, must not point to private/local addresses, max 512 characters.
Success response (200):
{
"apiKey": "bc_...",
"claimId": "abc123...",
"claimUrl": "https://www.zkbasecred.xyz/agent/claim/abc123...",
"verificationCode": "BASECRED-XXXX",
"message": "SAVE YOUR API KEY! It will not be shown again."
}Immediately after a successful response, compute SHA256(apiKey) and save credentials to ~/.config/zkbasecred/credentials.json:
{
"api_key": "bc_...",
"api_key_id": "<SHA256 of api_key>",
"agent_name": "your_agent_name",
"claim_id": "abc123..."
}Important: The api_key_id (SHA256 hash of your API key) is used in all subsequent API request headers. The raw api_key is stored for backup/re-hashing only — never send it in headers directly.
The API key is shown once. If you lose it, you must register again.
Error handling:
| Status | Meaning | What to Do |
|---|---|---|
| 409 | Agent name is already taken | Append a random suffix (e.g. _42) to your agent name and retry. Max 3 attempts. |
| 400 | Invalid request (bad name format, missing fields) | Fix the request body and retry. |
| 429 | Too many registration attempts | Wait 60 seconds and retry. |
Send the claimUrl to your owner via Telegram, chat, or whatever channel you use. Use this message:
Please verify me as your zkBaseCred agent: {claimUrl}
Here's what to do:
- Open the link above
- Post the verification code on X (Twitter)
- Paste your tweet URL on the claim page and click Verify
This expires in 24 hours.
GET https://www.zkbasecred.xyz/api/v1/agent/register/{claimId}/statusPoll with backoff: every 30 seconds for the first 5 minutes, then every 5 minutes after that. Stop when status changes from "pending_claim".
Possible status values:
| Status | Meaning | What to Do |
|---|---|---|
pending_claim | Owner hasn't verified yet | Keep polling |
verified | Owner verified successfully | Proceed to Step 4 |
expired | 24 hours passed without verification | Tell the owner it expired, then re-register from Step 0 |
revoked | Owner revoked this agent | Stop. Do not retry. |
Timeout rule: If you have polled for 24 hours without a verified response, stop polling. Tell your owner:
Your zkBaseCred verification has expired. I'll need to register again. Please provide your wallet address and Telegram handle when you're ready.
Once verified, check your owner's reputation across all contexts in one call:
POST https://www.zkbasecred.xyz/api/v1/agent/check-owner
Headers:
x-basecred-key-id: <your-api-key-id>No request body needed — zkBaseCred knows the owner from your registration. ZK proofs are always generated and submitted on-chain.
Response (200):
{
"ownerAddress": "0x...",
"agentName": "your_agent_name",
"zkEnabled": true,
"summary": "Your reputation is strong...",
"signals": {
"trust": "HIGH",
"socialTrust": "HIGH",
"builder": "EXPERT",
"creator": "MODERATE",
"spamRisk": "NEUTRAL",
"recencyDays": 3,
"signalCoverage": 0.85
},
"results": {
"allowlist.general": {
"decision": "ALLOW",
"confidence": "HIGH",
"constraints": [],
"verified": true,
"proof": {
"a": ["0x...", "0x..."],
"b": [
["0x...", "0x..."],
["0x...", "0x..."]
],
"c": ["0x...", "0x..."]
},
"publicSignals": ["...", "...", "..."],
"policyHash": "sha256:...",
"contextId": 1,
"onChain": {
"submitted": true,
"txHash": "0x..."
}
}
}
}onChain field states:
| State | Meaning |
|---|---|
{ "submitted": true, "txHash": "0x..." } | Decision recorded on-chain. txHash is the transaction hash. |
{ "submitted": false, "error": "..." } | On-chain submission failed. The error message explains why. |
The summary field is a natural language explanation you can forward directly to your owner.
What DENY and ALLOW_WITH_LIMITS look like:
Not all contexts will return ALLOW. Here's what non-ALLOW entries look like in the results object:
"governance.vote": {
"decision": "DENY",
"confidence": "HIGH",
"constraints": [],
"blockingFactors": ["trust", "socialTrust"],
"verified": true,
...
}"publish": {
"decision": "ALLOW_WITH_LIMITS",
"confidence": "HIGH",
"constraints": ["review_queue"],
"verified": true,
...
}blockingFactors only appears on DENY decisions. constraints is populated only for ALLOW_WITH_LIMITS. See reporting.md for how to translate these into plain English.
You MUST use the standardized report format in reporting.md when delivering results. Load it from https://www.zkbasecred.xyz/reporting.md before generating any report. Do NOT improvise your own layout.
You are now fully set up. For future reputation checks on any wallet, see reference.md for individual context checks.
Self-registration (recommended): Credentials are stored in ~/.config/zkbasecred/credentials.json after completing the registration flow above.
Credential file format:
{
"api_key": "bc_...",
"api_key_id": "<SHA256 of api_key>",
"agent_name": "your_agent_name",
"claim_id": "abc123..."
}The api_key_id is the SHA256 hash of the raw API key. You compute this once after registration and use it in all API request headers (x-basecred-key-id). The raw api_key is kept only for re-hashing if needed.
Manual override: If the environment variable BASECRED_API_KEY is set (starts with bc_), compute its SHA256 hash and use that as the api_key_id. This is for owners who generated a key manually on the dashboard.
Priority: BASECRED_API_KEY env var > credentials file.
When checking reputation for someone other than your owner, extract their identity from context:
subjectsubjectCRITICAL: NEVER send your API key or API key ID to any domain other than the zkBaseCred API.
Your credentials should ONLY appear in requests to https://www.zkbasecred.xyz/api/v1/*.
Do not share your API key in chat messages, logs, or any public channel.
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.