Create Attestation
curl --request POST \
--url https://api-mainnet.onzks.com/v1/trust/attestations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"subject": "<string>",
"schema": "<string>",
"data": {
"data.title": "<string>",
"data.description": "<string>",
"data.category": "<string>",
"data.value": "<string>",
"data.metadata": {},
"data.evidence": [
{
"data.evidence[].type": "<string>",
"data.evidence[].value": "<string>",
"data.evidence[].description": "<string>"
}
]
},
"signature": "<string>",
"expiry": "<string>",
"revocable": true,
"public": true,
"tags": [
{}
]
}
'import requests
url = "https://api-mainnet.onzks.com/v1/trust/attestations"
payload = {
"subject": "<string>",
"schema": "<string>",
"data": {
"data.title": "<string>",
"data.description": "<string>",
"data.category": "<string>",
"data.value": "<string>",
"data.metadata": {},
"data.evidence": [
{
"data.evidence[].type": "<string>",
"data.evidence[].value": "<string>",
"data.evidence[].description": "<string>"
}
]
},
"signature": "<string>",
"expiry": "<string>",
"revocable": True,
"public": True,
"tags": [{}]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
subject: '<string>',
schema: '<string>',
data: {
'data.title': '<string>',
'data.description': '<string>',
'data.category': '<string>',
'data.value': '<string>',
'data.metadata': {},
'data.evidence': [
{
'data.evidence[].type': '<string>',
'data.evidence[].value': '<string>',
'data.evidence[].description': '<string>'
}
]
},
signature: '<string>',
expiry: '<string>',
revocable: true,
public: true,
tags: [{}]
})
};
fetch('https://api-mainnet.onzks.com/v1/trust/attestations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-mainnet.onzks.com/v1/trust/attestations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'subject' => '<string>',
'schema' => '<string>',
'data' => [
'data.title' => '<string>',
'data.description' => '<string>',
'data.category' => '<string>',
'data.value' => '<string>',
'data.metadata' => [
],
'data.evidence' => [
[
'data.evidence[].type' => '<string>',
'data.evidence[].value' => '<string>',
'data.evidence[].description' => '<string>'
]
]
],
'signature' => '<string>',
'expiry' => '<string>',
'revocable' => true,
'public' => true,
'tags' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-mainnet.onzks.com/v1/trust/attestations"
payload := strings.NewReader("{\n \"subject\": \"<string>\",\n \"schema\": \"<string>\",\n \"data\": {\n \"data.title\": \"<string>\",\n \"data.description\": \"<string>\",\n \"data.category\": \"<string>\",\n \"data.value\": \"<string>\",\n \"data.metadata\": {},\n \"data.evidence\": [\n {\n \"data.evidence[].type\": \"<string>\",\n \"data.evidence[].value\": \"<string>\",\n \"data.evidence[].description\": \"<string>\"\n }\n ]\n },\n \"signature\": \"<string>\",\n \"expiry\": \"<string>\",\n \"revocable\": true,\n \"public\": true,\n \"tags\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-mainnet.onzks.com/v1/trust/attestations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"subject\": \"<string>\",\n \"schema\": \"<string>\",\n \"data\": {\n \"data.title\": \"<string>\",\n \"data.description\": \"<string>\",\n \"data.category\": \"<string>\",\n \"data.value\": \"<string>\",\n \"data.metadata\": {},\n \"data.evidence\": [\n {\n \"data.evidence[].type\": \"<string>\",\n \"data.evidence[].value\": \"<string>\",\n \"data.evidence[].description\": \"<string>\"\n }\n ]\n },\n \"signature\": \"<string>\",\n \"expiry\": \"<string>\",\n \"revocable\": true,\n \"public\": true,\n \"tags\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-mainnet.onzks.com/v1/trust/attestations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"subject\": \"<string>\",\n \"schema\": \"<string>\",\n \"data\": {\n \"data.title\": \"<string>\",\n \"data.description\": \"<string>\",\n \"data.category\": \"<string>\",\n \"data.value\": \"<string>\",\n \"data.metadata\": {},\n \"data.evidence\": [\n {\n \"data.evidence[].type\": \"<string>\",\n \"data.evidence[].value\": \"<string>\",\n \"data.evidence[].description\": \"<string>\"\n }\n ]\n },\n \"signature\": \"<string>\",\n \"expiry\": \"<string>\",\n \"revocable\": true,\n \"public\": true,\n \"tags\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"attestationId": "<string>",
"attestation": {
"id": "<string>",
"subject": "<string>",
"issuer": "<string>",
"schema": "<string>",
"data": {},
"signature": "<string>",
"createdAt": "<string>",
"expiry": "<string>",
"revocable": true,
"public": true,
"status": "<string>",
"tags": [
{}
]
},
"verification": {
"verified": true,
"verificationMethod": "<string>",
"verificationTimestamp": "<string>",
"trustScore": 123
},
"timestamp": "<string>"
}Trust Layer
Create Attestation
Create a new trust attestation for a subject
POST
/
v1
/
trust
/
attestations
Create Attestation
curl --request POST \
--url https://api-mainnet.onzks.com/v1/trust/attestations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"subject": "<string>",
"schema": "<string>",
"data": {
"data.title": "<string>",
"data.description": "<string>",
"data.category": "<string>",
"data.value": "<string>",
"data.metadata": {},
"data.evidence": [
{
"data.evidence[].type": "<string>",
"data.evidence[].value": "<string>",
"data.evidence[].description": "<string>"
}
]
},
"signature": "<string>",
"expiry": "<string>",
"revocable": true,
"public": true,
"tags": [
{}
]
}
'import requests
url = "https://api-mainnet.onzks.com/v1/trust/attestations"
payload = {
"subject": "<string>",
"schema": "<string>",
"data": {
"data.title": "<string>",
"data.description": "<string>",
"data.category": "<string>",
"data.value": "<string>",
"data.metadata": {},
"data.evidence": [
{
"data.evidence[].type": "<string>",
"data.evidence[].value": "<string>",
"data.evidence[].description": "<string>"
}
]
},
"signature": "<string>",
"expiry": "<string>",
"revocable": True,
"public": True,
"tags": [{}]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
subject: '<string>',
schema: '<string>',
data: {
'data.title': '<string>',
'data.description': '<string>',
'data.category': '<string>',
'data.value': '<string>',
'data.metadata': {},
'data.evidence': [
{
'data.evidence[].type': '<string>',
'data.evidence[].value': '<string>',
'data.evidence[].description': '<string>'
}
]
},
signature: '<string>',
expiry: '<string>',
revocable: true,
public: true,
tags: [{}]
})
};
fetch('https://api-mainnet.onzks.com/v1/trust/attestations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-mainnet.onzks.com/v1/trust/attestations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'subject' => '<string>',
'schema' => '<string>',
'data' => [
'data.title' => '<string>',
'data.description' => '<string>',
'data.category' => '<string>',
'data.value' => '<string>',
'data.metadata' => [
],
'data.evidence' => [
[
'data.evidence[].type' => '<string>',
'data.evidence[].value' => '<string>',
'data.evidence[].description' => '<string>'
]
]
],
'signature' => '<string>',
'expiry' => '<string>',
'revocable' => true,
'public' => true,
'tags' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-mainnet.onzks.com/v1/trust/attestations"
payload := strings.NewReader("{\n \"subject\": \"<string>\",\n \"schema\": \"<string>\",\n \"data\": {\n \"data.title\": \"<string>\",\n \"data.description\": \"<string>\",\n \"data.category\": \"<string>\",\n \"data.value\": \"<string>\",\n \"data.metadata\": {},\n \"data.evidence\": [\n {\n \"data.evidence[].type\": \"<string>\",\n \"data.evidence[].value\": \"<string>\",\n \"data.evidence[].description\": \"<string>\"\n }\n ]\n },\n \"signature\": \"<string>\",\n \"expiry\": \"<string>\",\n \"revocable\": true,\n \"public\": true,\n \"tags\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-mainnet.onzks.com/v1/trust/attestations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"subject\": \"<string>\",\n \"schema\": \"<string>\",\n \"data\": {\n \"data.title\": \"<string>\",\n \"data.description\": \"<string>\",\n \"data.category\": \"<string>\",\n \"data.value\": \"<string>\",\n \"data.metadata\": {},\n \"data.evidence\": [\n {\n \"data.evidence[].type\": \"<string>\",\n \"data.evidence[].value\": \"<string>\",\n \"data.evidence[].description\": \"<string>\"\n }\n ]\n },\n \"signature\": \"<string>\",\n \"expiry\": \"<string>\",\n \"revocable\": true,\n \"public\": true,\n \"tags\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-mainnet.onzks.com/v1/trust/attestations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"subject\": \"<string>\",\n \"schema\": \"<string>\",\n \"data\": {\n \"data.title\": \"<string>\",\n \"data.description\": \"<string>\",\n \"data.category\": \"<string>\",\n \"data.value\": \"<string>\",\n \"data.metadata\": {},\n \"data.evidence\": [\n {\n \"data.evidence[].type\": \"<string>\",\n \"data.evidence[].value\": \"<string>\",\n \"data.evidence[].description\": \"<string>\"\n }\n ]\n },\n \"signature\": \"<string>\",\n \"expiry\": \"<string>\",\n \"revocable\": true,\n \"public\": true,\n \"tags\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"attestationId": "<string>",
"attestation": {
"id": "<string>",
"subject": "<string>",
"issuer": "<string>",
"schema": "<string>",
"data": {},
"signature": "<string>",
"createdAt": "<string>",
"expiry": "<string>",
"revocable": true,
"public": true,
"status": "<string>",
"tags": [
{}
]
},
"verification": {
"verified": true,
"verificationMethod": "<string>",
"verificationTimestamp": "<string>",
"trustScore": 123
},
"timestamp": "<string>"
}Overview
Create a new trust attestation that provides verifiable proof of a relationship, skill, or attribute. This endpoint allows users to issue attestations that can be used for trust scoring, reputation building, and identity verification.Use this endpoint to create verifiable attestations that can be used for trust scoring, reputation systems, and identity verification. Attestations are cryptographically signed and immutable.
Parameters
string
required
The identity being attested to (ZKS ID or wallet address)
string
required
The attestation schema identifier
skill- Skill or expertise attestationrelationship- Relationship attestationachievement- Achievement attestationreputation- Reputation attestationidentity- Identity verification attestationcustom- Custom schema
object
required
Attestation data payload
Show data properties
Show data properties
string
required
Cryptographic signature of the attestation
string
ISO 8601 timestamp when attestation expires (optional)
boolean
Whether the attestation can be revoked (default: true)
boolean
Whether the attestation is publicly visible (default: true)
array
Tags for categorization and discovery
Response
boolean
Indicates if the attestation was created successfully
string
Unique identifier of the created attestation
object
Created attestation details
Show attestation properties
Show attestation properties
string
Attestation identifier
string
Attested identity
string
Attestation issuer
string
Attestation schema
object
Attestation data
string
Attestation signature
string
ISO 8601 timestamp of creation
string
ISO 8601 timestamp of expiry (if set)
boolean
Whether attestation can be revoked
boolean
Whether attestation is publicly visible
string
Attestation status (active, expired, revoked)
array
Attestation tags
object
string
ISO 8601 timestamp of the response
Examples
curl -X POST "https://api.onzks.com/v1/trust/attestations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "alice.zks",
"schema": "skill",
"data": {
"title": "Solidity Developer",
"description": "Expert in smart contract development",
"category": "programming",
"value": "expert",
"metadata": {
"yearsExperience": 5,
"projects": ["DeFi Protocol", "NFT Marketplace"],
"certifications": ["Certified Solidity Developer"]
},
"evidence": [
{
"type": "url",
"value": "https://github.com/alice/solidity-projects",
"description": "GitHub repository with Solidity projects"
},
{
"type": "document",
"value": "certificate.pdf",
"description": "Certification document"
}
]
},
"signature": "0xabcdef1234567890...",
"expiry": "2025-01-20T15:45:00Z",
"revocable": true,
"public": true,
"tags": ["solidity", "blockchain", "developer"]
}'
curl -X POST "https://api.onzks.com/v1/trust/attestations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "bob.zks",
"schema": "relationship",
"data": {
"title": "Business Partner",
"description": "Long-term business partnership",
"category": "business",
"value": "trusted",
"metadata": {
"relationshipType": "business_partner",
"duration": "3 years",
"projects": ["Joint Venture", "Consulting"]
},
"evidence": [
{
"type": "transaction",
"value": "0x1234567890abcdef...",
"description": "Business transaction history"
}
]
},
"signature": "0x1234567890abcdef...",
"revocable": true,
"public": true,
"tags": ["business", "partnership", "trusted"]
}'
curl -X POST "https://api.onzks.com/v1/trust/attestations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "charlie.zks",
"schema": "achievement",
"data": {
"title": "DeFi Protocol Launch",
"description": "Successfully launched a DeFi protocol",
"category": "achievement",
"value": "completed",
"metadata": {
"protocolName": "YieldFarm Protocol",
"launchDate": "2024-01-15",
"totalValueLocked": "1000000",
"users": 500
},
"evidence": [
{
"type": "url",
"value": "https://yieldfarm.xyz",
"description": "Protocol website"
},
{
"type": "transaction",
"value": "0xabcdef1234567890...",
"description": "Protocol deployment transaction"
}
]
},
"signature": "0x9876543210fedcba...",
"revocable": false,
"public": true,
"tags": ["defi", "protocol", "launch", "achievement"]
}'
async function createAttestation(attestationData) {
const {
subject,
schema,
data,
signature,
expiry,
revocable = true,
public: isPublic = true,
tags = []
} = attestationData;
const requestBody = {
subject,
schema,
data,
signature,
revocable,
public: isPublic,
tags
};
if (expiry) {
requestBody.expiry = expiry;
}
const response = await fetch('https://api.onzks.com/v1/trust/attestations', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});
const result = await response.json();
if (result.success) {
console.log(`✅ Attestation created: ${result.attestationId}`);
console.log(`Subject: ${result.attestation.subject}`);
console.log(`Schema: ${result.attestation.schema}`);
console.log(`Status: ${result.attestation.status}`);
console.log(`Verified: ${result.verification.verified}`);
} else {
console.error('Failed to create attestation:', result.message);
}
return result;
}
// Usage examples
await createAttestation({
subject: 'alice.zks',
schema: 'skill',
data: {
title: 'Solidity Developer',
description: 'Expert in smart contract development',
category: 'programming',
value: 'expert',
metadata: {
yearsExperience: 5,
projects: ['DeFi Protocol', 'NFT Marketplace']
},
evidence: [
{
type: 'url',
value: 'https://github.com/alice/solidity-projects',
description: 'GitHub repository with Solidity projects'
}
]
},
signature: '0xabcdef1234567890...',
tags: ['solidity', 'blockchain', 'developer']
});
import requests
import json
def create_attestation(subject, schema, data, signature, expiry=None, revocable=True, public=True, tags=None):
if tags is None:
tags = []
request_body = {
'subject': subject,
'schema': schema,
'data': data,
'signature': signature,
'revocable': revocable,
'public': public,
'tags': tags
}
if expiry:
request_body['expiry'] = expiry
response = requests.post(
'https://api.onzks.com/v1/trust/attestations',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json=request_body
)
result = response.json()
if result['success']:
print(f"✅ Attestation created: {result['attestationId']}")
print(f"Subject: {result['attestation']['subject']}")
print(f"Schema: {result['attestation']['schema']}")
print(f"Status: {result['attestation']['status']}")
print(f"Verified: {result['verification']['verified']}")
else:
print(f"Failed to create attestation: {result['message']}")
return result
# Usage examples
create_attestation(
subject='alice.zks',
schema='skill',
data={
'title': 'Solidity Developer',
'description': 'Expert in smart contract development',
'category': 'programming',
'value': 'expert',
'metadata': {
'yearsExperience': 5,
'projects': ['DeFi Protocol', 'NFT Marketplace']
},
'evidence': [
{
'type': 'url',
'value': 'https://github.com/alice/solidity-projects',
'description': 'GitHub repository with Solidity projects'
}
]
},
signature='0xabcdef1234567890...',
tags=['solidity', 'blockchain', 'developer']
)
Response Example
{
"success": true,
"attestationId": "att_1234567890abcdef",
"attestation": {
"id": "att_1234567890abcdef",
"subject": "alice.zks",
"issuer": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"schema": "skill",
"data": {
"title": "Solidity Developer",
"description": "Expert in smart contract development",
"category": "programming",
"value": "expert",
"metadata": {
"yearsExperience": 5,
"projects": ["DeFi Protocol", "NFT Marketplace"],
"certifications": ["Certified Solidity Developer"]
},
"evidence": [
{
"type": "url",
"value": "https://github.com/alice/solidity-projects",
"description": "GitHub repository with Solidity projects"
},
{
"type": "document",
"value": "certificate.pdf",
"description": "Certification document"
}
]
},
"signature": "0xabcdef1234567890...",
"createdAt": "2024-01-20T15:45:00Z",
"expiry": "2025-01-20T15:45:00Z",
"revocable": true,
"public": true,
"status": "active",
"tags": ["solidity", "blockchain", "developer"]
},
"verification": {
"verified": true,
"verificationMethod": "signature_verification",
"verificationTimestamp": "2024-01-20T15:45:00Z",
"trustScore": 85.5
},
"timestamp": "2024-01-20T15:45:00Z"
}
Use Cases
1. Skill Attestation System
Create a skill attestation system:async function createSkillAttestation(subject, skill, evidence) {
const attestationData = {
subject,
schema: 'skill',
data: {
title: skill.name,
description: skill.description,
category: skill.category,
value: skill.level,
metadata: {
yearsExperience: skill.experience,
projects: skill.projects,
certifications: skill.certifications
},
evidence: evidence.map(ev => ({
type: ev.type,
value: ev.value,
description: ev.description
}))
},
signature: await signAttestation(subject, skill),
tags: skill.tags
};
return await createAttestation(attestationData);
}
// Usage
const skill = {
name: 'React Developer',
description: 'Expert in React and frontend development',
category: 'programming',
level: 'expert',
experience: 3,
projects: ['E-commerce Platform', 'Dashboard App'],
certifications: ['React Certification'],
tags: ['react', 'javascript', 'frontend']
};
const evidence = [
{
type: 'url',
value: 'https://github.com/alice/react-projects',
description: 'GitHub repository with React projects'
}
];
await createSkillAttestation('alice.zks', skill, evidence);
2. Relationship Attestation
Create relationship attestations:async function createRelationshipAttestation(subject, relationship) {
const attestationData = {
subject,
schema: 'relationship',
data: {
title: relationship.title,
description: relationship.description,
category: relationship.category,
value: relationship.trustLevel,
metadata: {
relationshipType: relationship.type,
duration: relationship.duration,
projects: relationship.projects
},
evidence: relationship.evidence
},
signature: await signAttestation(subject, relationship),
tags: relationship.tags
};
return await createAttestation(attestationData);
}
// Usage
const relationship = {
title: 'Business Partner',
description: 'Long-term business partnership',
category: 'business',
trustLevel: 'trusted',
type: 'business_partner',
duration: '3 years',
projects: ['Joint Venture', 'Consulting'],
evidence: [
{
type: 'transaction',
value: '0x1234567890abcdef...',
description: 'Business transaction history'
}
],
tags: ['business', 'partnership', 'trusted']
};
await createRelationshipAttestation('bob.zks', relationship);
3. Achievement Attestation
Create achievement attestations:async function createAchievementAttestation(subject, achievement) {
const attestationData = {
subject,
schema: 'achievement',
data: {
title: achievement.title,
description: achievement.description,
category: achievement.category,
value: achievement.status,
metadata: {
completionDate: achievement.completionDate,
metrics: achievement.metrics,
impact: achievement.impact
},
evidence: achievement.evidence
},
signature: await signAttestation(subject, achievement),
revocable: false, // Achievements are typically not revocable
tags: achievement.tags
};
return await createAttestation(attestationData);
}
// Usage
const achievement = {
title: 'DeFi Protocol Launch',
description: 'Successfully launched a DeFi protocol',
category: 'achievement',
status: 'completed',
completionDate: '2024-01-15',
metrics: {
totalValueLocked: '1000000',
users: 500,
transactions: 10000
},
impact: 'High',
evidence: [
{
type: 'url',
value: 'https://yieldfarm.xyz',
description: 'Protocol website'
},
{
type: 'transaction',
value: '0xabcdef1234567890...',
description: 'Protocol deployment transaction'
}
],
tags: ['defi', 'protocol', 'launch', 'achievement']
};
await createAchievementAttestation('charlie.zks', achievement);
4. Batch Attestation Creation
Create multiple attestations at once:async function createBatchAttestations(attestations) {
const results = [];
for (const attestation of attestations) {
try {
const result = await createAttestation(attestation);
results.push({ success: true, result });
} catch (error) {
results.push({ success: false, error: error.message });
}
}
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Successfully created ${successful.length} attestations`);
if (failed.length > 0) {
console.log(`Failed to create ${failed.length} attestations`);
}
return results;
}
5. Attestation Templates
Use predefined templates:const attestationTemplates = {
skill: {
schema: 'skill',
requiredFields: ['title', 'description', 'category', 'value'],
optionalFields: ['metadata', 'evidence'],
defaultTags: ['skill', 'attestation']
},
relationship: {
schema: 'relationship',
requiredFields: ['title', 'description', 'category', 'value'],
optionalFields: ['metadata', 'evidence'],
defaultTags: ['relationship', 'attestation']
},
achievement: {
schema: 'achievement',
requiredFields: ['title', 'description', 'category', 'value'],
optionalFields: ['metadata', 'evidence'],
defaultTags: ['achievement', 'attestation']
}
};
function createAttestationFromTemplate(template, data) {
const templateConfig = attestationTemplates[template];
if (!templateConfig) {
throw new Error(`Unknown template: ${template}`);
}
// Validate required fields
for (const field of templateConfig.requiredFields) {
if (!data[field]) {
throw new Error(`Missing required field: ${field}`);
}
}
return {
schema: templateConfig.schema,
data: {
...data,
tags: [...(data.tags || []), ...templateConfig.defaultTags]
}
};
}
Best Practices
1. Signature Verification
Always verify signatures before creating attestations:async function verifyAttestationSignature(attestation, signature) {
const message = JSON.stringify(attestation);
const recoveredAddress = await recoverAddress(message, signature);
return recoveredAddress === attestation.issuer;
}
2. Evidence Validation
Validate evidence before creating attestations:function validateEvidence(evidence) {
const validTypes = ['url', 'document', 'transaction', 'image', 'video'];
return evidence.every(ev => {
return validTypes.includes(ev.type) &&
ev.value &&
ev.description;
});
}
3. Expiry Management
Handle attestation expiry:function checkAttestationExpiry(attestation) {
if (!attestation.expiry) {
return { expired: false, daysRemaining: null };
}
const expiryDate = new Date(attestation.expiry);
const now = new Date();
const daysRemaining = Math.ceil((expiryDate - now) / (1000 * 60 * 60 * 24));
return {
expired: now > expiryDate,
daysRemaining: daysRemaining > 0 ? daysRemaining : 0
};
}
4. Privacy Controls
Implement privacy controls:function createPrivateAttestation(attestationData) {
return {
...attestationData,
public: false,
tags: [...(attestationData.tags || []), 'private']
};
}
function createPublicAttestation(attestationData) {
return {
...attestationData,
public: true,
tags: [...(attestationData.tags || []), 'public']
};
}
Related Endpoints
- Get Attestations - Retrieve attestations
- Revoke Attestation - Revoke an attestation
- Evaluate Policy - Evaluate trust policies
- Get Modules - Get available trust modules
Troubleshooting
”Invalid signature”
Cause: The signature doesn’t match the attestation data. Solution:- Verify the signature is correctly generated
- Ensure the message being signed matches the attestation data
- Check that the correct private key is being used
”Invalid schema”
Cause: Unsupported schema identifier. Solution:- Use supported schemas: skill, relationship, achievement, reputation, identity, custom
- Check for typos in the schema name
”Missing required fields”
Cause: Required fields are missing from the attestation data. Solution:- Include all required fields for the schema
- Check the schema documentation for required fields
- Validate the data structure before submission
”Attestation already exists”
Cause: An identical attestation already exists. Solution:- Check if the attestation already exists
- Modify the attestation data to make it unique
- Consider updating the existing attestation instead
Rate Limits
Attestation creation requests are subject to rate limits:- Free tier: 10 attestations per minute
- Starter tier: 50 attestations per minute
- Professional tier: 200 attestations per minute
- Enterprise tier: Custom limits
⌘I