Getting Started
This guide walks you through using the L{CORE} Attestor SDK to create verified claims from external data sources. Claims can be stored in the L{CORE} privacy layer (via Cartesi rollup on Arbitrum Sepolia) or verified off-chain.
Overview
L{CORE} is built on two core technologies:
- Reclaim Protocol - zkTLS proofs for data verification
- Cartesi - Deterministic rollup for on-chain state
flowchart LR
A[Your App] --> B[Attestor SDK]
B --> C[TEE Attestor]
C --> D[Reclaim Protocol]
C --> E[Cartesi Rollup]
E --> F[Arbitrum Sepolia]
Installation
npm install @reclaimprotocol/attestor-core
For NodeJS environments, download the ZK circuit files:
npm run download:zk-files
Creating Your First Claim
A "claim" is a cryptographically signed assertion that data from an external API matches certain criteria. The attestor verifies this without seeing your secrets (passwords, tokens, etc.).
Basic Example
import { createClaimOnAttestor } from '@reclaimprotocol/attestor-core'
const result = await createClaimOnAttestor({
// Provider name - 'http' is the generic HTTP provider
name: 'http',
// Public parameters (visible to attestor and verifiers)
params: {
url: 'https://api.example.com/user/profile',
method: 'GET',
// What to look for in the response
responseMatches: [
{ type: 'contains', value: '"verified": true' }
]
},
// Secret parameters (hidden from attestor via TLS redaction)
secretParams: {
headers: {
'Authorization': 'Bearer your-secret-token'
}
},
// Your wallet private key (signs the claim)
ownerPrivateKey: '0x...',
// Attestor server to use
client: { url: 'wss://attestor.reclaimprotocol.org/ws' }
})
// Check result
if (result.error) {
console.error('Claim failed:', result.error)
} else {
console.log('Claim created successfully!')
console.log('Claim data:', result.claim)
console.log('Attestor signature:', result.signatures.claimSignature)
}
Verifying a Claim
Anyone can verify a claim using the attestor's signature:
import { assertValidClaimSignatures } from '@reclaimprotocol/attestor-core'
// Throws an error if the claim or signature is invalid
await assertValidClaimSignatures(result)
// Or verify just the claim portion
await assertValidClaimSignatures({
claim: result.claim,
signatures: {
claimSignature: result.signatures.claimSignature,
attestorAddress: result.signatures.attestorAddress
}
})
L{CORE} Integration
When L{CORE} is enabled, attestations are automatically stored in the Cartesi rollup for on-chain verification.
Querying L{CORE} Data
Query the Cartesi node directly using the inspect endpoint:
// Query all provider schemas
const query = { type: 'all_provider_schemas', params: {} };
const url = `http://${CARTESI_NODE_IP}:10000/inspect/${encodeURIComponent(JSON.stringify(query))}`;
const response = await fetch(url);
const data = await response.json();
Available Query Types
| Query Type | Description |
|---|---|
all_provider_schemas | List registered provider schemas |
attestations_by_owner | Get attestations for a wallet address |
check_access | Verify if a grantee has access |
aggregate_by_bucket | Get anonymized bucket statistics |
Example: Query Attestations by Owner
const query = {
type: 'attestations_by_owner',
params: {
owner: '0x1234567890abcdef1234567890abcdef12345678',
limit: 10,
offset: 0
}
};
const url = `http://${CARTESI_NODE_IP}:10000/inspect/${encodeURIComponent(JSON.stringify(query))}`;
const response = await fetch(url);
Production Endpoints
| Service | Endpoint |
|---|---|
| Cartesi Node | http://${CARTESI_NODE_IP}:10000 |
| Attestor API | http://${ATTESTOR_IP}:8001 |
Contract Addresses (Arbitrum Sepolia)
| Contract | Address |
|---|---|
| DApp | 0xAE0863401D5B953b89cad8a5E7c98f5136E9C26d |
| InputBox | 0x59b22D57D4f067708AB0c00552767405926dc768 |
Response Matching
The responseMatches parameter defines what the attestor looks for in the API response:
Contains Match
responseMatches: [
{ type: 'contains', value: 'success' }
]
Regex Match with Extraction
Named capture groups extract values into the claim context:
responseMatches: [
{
type: 'regex',
value: '"balance":\\s*(?<balance>\\d+)'
}
]
// Result: claim.context.extractedParameters.balance = "1000"
JSONPath Match
responseMatches: [
{ type: 'jsonPath', value: '$.data.verified' }
]
Response Redactions
Control what parts of the response are visible to the attestor:
JSONPath Redaction
Only reveal specific JSON fields:
params: {
url: 'https://api.example.com/profile',
method: 'GET',
responseRedactions: [
{ jsonPath: '$.email' }, // Reveal email
{ jsonPath: '$.verified' } // Reveal verified status
],
responseMatches: [
{ type: 'contains', value: '"verified": true' }
]
}
TOPRF Hashing
Hash sensitive data consistently (for deduplication without revealing values):
responseRedactions: [
{ jsonPath: '$.userId', hash: 'oprf' }
]
CLI Usage
Create claims from the command line:
# Create a claim using a JSON config file
npm run create:claim -- --json claim-params.json
# Use a specific attestor
npm run create:claim -- --json claim-params.json --attestor wss://attestor.reclaimprotocol.org/ws
# Use local attestor (auto-started)
npm run create:claim -- --json claim-params.json --attestor local
# Use gnark ZK engine (faster on Linux x64/arm64)
npm run create:claim -- --json claim-params.json --zk gnark
Example claim-params.json:
{
"name": "http",
"params": {
"url": "https://api.example.com/verify",
"method": "GET",
"responseMatches": [
{ "type": "contains", "value": "verified" }
]
},
"secretParams": {
"headers": {
"Authorization": "Bearer {{API_TOKEN}}"
}
}
}
Environment variables in {{...}} are replaced from your .env file.
Error Handling
const result = await createClaimOnAttestor({ ... })
if (result.error) {
// Claim verification failed (attestor processed request but data didn't match)
console.error('Verification error:', result.error.message)
console.error('Error code:', result.error.code)
} else {
// Success
console.log('Claim:', result.claim)
}
// Network/connection errors throw exceptions
try {
const result = await createClaimOnAttestor({ ... })
} catch (err) {
// Connection failed, attestor unreachable, etc.
console.error('Connection error:', err)
}
Next Steps
- HTTP Provider Details - Full HTTP provider configuration
- Claim Creation Deep Dive - How claims work internally
- Running Your Own Attestor - Deploy your own attestor server
- L{CORE} Architecture - Privacy layer architecture
- L{CORE} Deployment - Deploy to EigenCloud
- Browser/Mobile Integration - React Native and browser usage