ATProto lexicon definitions and TypeScript types for the Hypercerts protocol — a system for tracking, evaluating, and funding impact work on the AT Protocol network.
CLAIMS ─ the core impact record and its parts
──────────────────────────────────────────────────────────────────────
activity ──────────┬──► collection ◄──┐ (recursive nesting)
(the hypercert) │ │ │
│ ▼ │
├──► contribution (role, timeframe)
├──► contributorInformation (identity, avatar)
├──► rights (licensing terms)
└──► workScope
├── cel (CEL expression)
└── tag (reusable scope atom)
CONTEXT ─ evidence, data, and social verification
──────────────────────────────────────────────────────────────────────
attachment ─────────────► activity / evaluation / ...
measurement ────────────► activity / ...
evaluation ─────────────► activity / attachment
└──────► measurement
acknowledgement ────────► activity / collection (bidirectional link)
FUNDING ─ payment records
──────────────────────────────────────────────────────────────────────
receipt ────────────────► activity (from funder → to recipient)
HYPERBOARDS ─ visual display layer (hyperboards.org)
──────────────────────────────────────────────────────────────────────
board ──────────────────► activity / collection
└── contributorConfig ► contributorInformation
displayProfile (per-user visual defaults)
CERTIFIED ─ shared lexicons (certified.app)
──────────────────────────────────────────────────────────────────────
location (geo coordinates, GeoJSON, H3, …)
actor/profile (user profile)
actor/organization (org metadata)
badge/definition ──► badge/award ──► badge/response
Every arrow (►) is a strongRef or union reference stored on the
AT Protocol network. Full field-level documentation is in
SCHEMAS.md.
npm install @hypercerts-org/lexiconimport {
HYPERCERTS_SCHEMAS,
ACTIVITY_NSID,
validate,
} from "@hypercerts-org/lexicon";
import { Agent } from "@atproto/api";
const agent = new Agent({ service: "https://bsky.social" });
// Register lexicons with the agent
agent.api.lex.add(...HYPERCERTS_SCHEMAS);
// Build a record
const record = {
$type: ACTIVITY_NSID,
title: "Reforestation in Amazon Basin 2024",
shortDescription: "Planted 5,000 native trees across 12 hectares",
createdAt: new Date().toISOString(),
};
// Validate before writing
const result = validate(ACTIVITY_NSID, record);
if (!result.valid) throw new Error(JSON.stringify(result.errors));
// Write to the network
await agent.api.com.atproto.repo.createRecord({
repo: agent.session?.did,
collection: ACTIVITY_NSID,
record,
});| Lexicon | NSID | Description |
|---|---|---|
| Activity | org.hypercerts.claim.activity |
The main hypercert record — describes impact work with title, description, contributors, work scope, timeframe, locations, and rights. |
| Contribution | org.hypercerts.claim.contribution |
Details about a specific contribution: role, description, and timeframe. |
| Contributor Information | org.hypercerts.claim.contributorInformation |
Identity record for a contributor: identifier (DID or URI), display name, and avatar. |
| Rights | org.hypercerts.claim.rights |
Licensing and rights terms (e.g. "CC BY-SA 4.0") attached to an activity. |
| Lexicon | NSID | Description |
|---|---|---|
| Collection | org.hypercerts.collection |
A named, weighted group of activities and/or other collections. Supports recursive nesting. Used for projects, portfolios, favourites, funding rounds, etc. |
| Lexicon | NSID | Description |
|---|---|---|
| Attachment | org.hypercerts.context.attachment |
Documents, reports, evidence, or other files linked to a record. |
| Measurement | org.hypercerts.context.measurement |
Quantitative data point (metric + unit + value) linked to one or more records. |
| Evaluation | org.hypercerts.context.evaluation |
An assessment of a record with evaluators, summary, score, and supporting measurements. |
| Acknowledgement | org.hypercerts.context.acknowledgement |
Bidirectional link: confirms or rejects inclusion of a record in another context. |
| Lexicon | NSID | Description |
|---|---|---|
| Tag | org.hypercerts.workscope.tag |
Reusable scope atom (topic, domain, method, …) with taxonomy support, aliases, and linked ontologies. |
| CEL Expression | org.hypercerts.workscope.cel |
Structured work scope using CEL expressions over tags. Embedded inline in activity records. |
| Lexicon | NSID | Description |
|---|---|---|
| Receipt | org.hypercerts.funding.receipt |
Records a payment from a funder to a recipient, with amount, currency, payment rail, and optional transaction ID. |
| Lexicon | NSID | Description |
|---|---|---|
| Board | org.hyperboards.board |
Visual presentation layer wrapping an activity or collection with background, colors, aspect ratio, and per-contributor styling. |
| Display Profile | org.hyperboards.displayProfile |
Per-user visual defaults (avatar, hover image, video, click-through URL) reusable across boards. Singleton record (literal:self). |
| Lexicon | NSID | Description |
|---|---|---|
| Location | app.certified.location |
Geographic reference using the Location Protocol (coordinates, GeoJSON, H3, WKT, etc.). |
| Profile | app.certified.actor.profile |
User account profile with display name, bio, avatar, and banner. |
| Organization | app.certified.actor.organization |
Organization metadata: legal structure, URLs, location, founding date. |
| Badge Definition | app.certified.badge.definition |
Defines a badge type with title, icon, and optional issuer allowlist. |
| Badge Award | app.certified.badge.award |
Awards a badge to a user, project, or activity. |
| Badge Response | app.certified.badge.response |
Recipient accepts or rejects a badge award. |
| EVM Link | app.certified.link.evm |
Verifiable ATProto DID ↔ EVM wallet link via EIP-712 signature. Extensible for future proof methods (e.g. ERC-1271, ERC-6492). |
Full property tables → SCHEMAS.md
Individual constants (recommended):
import { ACTIVITY_NSID, COLLECTION_NSID } from "@hypercerts-org/lexicon";Semantic object:
import { HYPERCERTS_NSIDS } from "@hypercerts-org/lexicon";
const id = HYPERCERTS_NSIDS.ACTIVITY;Type-based mapping:
import { HYPERCERTS_NSIDS_BY_TYPE } from "@hypercerts-org/lexicon";
const id = HYPERCERTS_NSIDS_BY_TYPE.OrgHypercertsClaimActivity;Lightweight bundle (no TypeScript types, smaller bundle):
import { schemas, validate, ids } from "@hypercerts-org/lexicon/lexicons";import { OrgHypercertsClaimActivity } from "@hypercerts-org/lexicon";
const activity: OrgHypercertsClaimActivity.Main = {
$type: "org.hypercerts.claim.activity",
title: "My Impact Work",
shortDescription: "...",
createdAt: new Date().toISOString(),
};import {
ACTIVITY_LEXICON_JSON, // raw JSON (untyped)
ACTIVITY_LEXICON_DOC, // LexiconDoc (typed)
} from "@hypercerts-org/lexicon";Or via semantic mapping objects:
import {
HYPERCERTS_LEXICON_JSON,
HYPERCERTS_LEXICON_DOC,
} from "@hypercerts-org/lexicon";
const doc = HYPERCERTS_LEXICON_DOC.ACTIVITY;import { ACTIVITY_NSID } from "@hypercerts-org/lexicon";
const activity = {
$type: ACTIVITY_NSID,
title: "Mangrove Restoration in Mombasa",
shortDescription: "Restored 3 hectares of mangrove forest",
// Structured work scope via CEL expression:
workScope: {
$type: "org.hypercerts.workscope.cel",
expression:
"scope.hasAll(['mangrove_restoration']) && location.country == 'KE'",
usedTags: [
{
uri: "at://did:plc:alice/org.hypercerts.workscope.tag/3k2abc",
cid: "...",
},
],
version: "v1",
createdAt: new Date().toISOString(),
},
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-12-31T23:59:59Z",
createdAt: new Date().toISOString(),
};import { COLLECTION_NSID } from "@hypercerts-org/lexicon";
const project = {
$type: COLLECTION_NSID,
type: "project",
title: "Carbon Offset Initiative",
shortDescription: "Activities focused on carbon reduction and reforestation",
items: [
{
itemIdentifier: {
uri: "at://did:plc:alice/org.hypercerts.claim.activity/3k2abc",
cid: "...",
},
},
{
itemIdentifier: {
uri: "at://did:plc:bob/org.hypercerts.claim.activity/7x9def",
cid: "...",
},
},
// Collections can contain other collections (recursive nesting):
{
itemIdentifier: {
uri: "at://did:plc:carol/org.hypercerts.collection/4m5ghi",
cid: "...",
},
},
],
createdAt: new Date().toISOString(),
};import { LOCATION_NSID } from "@hypercerts-org/lexicon";
// Decimal coordinates
const location = {
$type: LOCATION_NSID,
lpVersion: "1.0",
srs: "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
locationType: "coordinate-decimal",
location: { string: "-3.4653, -62.2159" },
name: "Amazon Research Station",
createdAt: new Date().toISOString(),
};
// GeoJSON
const geoLocation = {
$type: LOCATION_NSID,
lpVersion: "1.0",
srs: "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
locationType: "geojson-point",
location: { string: '{"type":"Point","coordinates":[-62.2159,-3.4653]}' },
name: "Research Station Alpha",
createdAt: new Date().toISOString(),
};When one user includes another's record (e.g. adding an activity to a collection), the owner can confirm or reject with an acknowledgement:
import { ACKNOWLEDGEMENT_NSID } from "@hypercerts-org/lexicon";
const ack = {
$type: ACKNOWLEDGEMENT_NSID,
subject: {
uri: "at://did:plc:bob/org.hypercerts.claim.activity/3k2abc",
cid: "bafy...",
},
context: {
uri: "at://did:plc:alice/org.hypercerts.collection/7x9def",
cid: "bafy...",
},
acknowledged: true, // false to reject
createdAt: new Date().toISOString(),
};import { ATTACHMENT_NSID } from "@hypercerts-org/lexicon";
const attachment = {
$type: ATTACHMENT_NSID,
title: "Field Survey Report",
contentType: "report",
subjects: [
{
uri: "at://did:plc:alice/org.hypercerts.claim.activity/abc123",
cid: "...",
},
],
content: [
{ uri: "https://example.com/reports/survey-2024.pdf" },
{ uri: "ipfs://Qm..." },
],
shortDescription: "Quarterly field survey documenting project progress",
createdAt: new Date().toISOString(),
};npm run gen-api # Regenerate TypeScript types from lexicons
npm run build # Build distributable bundles (ESM, CJS, types)
npm run check # Validate + typecheck + build (run before committing)
npm run lint # Check formatting (Prettier + ESLint)
npm run format # Auto-fix formatting
npm run gen-schemas-md # Regenerate SCHEMAS.md
npm run test # Run testsThe app.certified.link.evm record enables verifiable linking between
an ATProto DID and an EVM wallet address. The link is proven via a
cryptographic signature, allowing any verifier to confirm that the
wallet owner authorized the binding. Currently supports EOA wallets
via EIP-712 typed data signatures; the proof field is an open union
to allow future signature methods (e.g. ERC-1271, ERC-6492).
import { LINK_EVM_NSID } from "@hypercerts-org/lexicon";
const evmLinkRecord = {
$type: LINK_EVM_NSID,
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
proof: {
$type: "app.certified.link.evm#eip712Proof",
signature: "0xabc123...", // truncated for readability; real signatures are 130-132 hex chars
message: {
$type: "app.certified.link.evm#eip712Message",
did: "did:plc:alice",
evmAddress: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
chainId: "1",
timestamp: "1709500000",
nonce: "0",
},
},
createdAt: new Date().toISOString(),
};Key fields:
address(required): 0x-prefixed EVM wallet address (EIP-55 checksummed, 42 chars)proof(required): Open union containing the cryptographic proof of wallet ownership. Each variant bundles its signature with the corresponding message format. Currently the only variant is#eip712Prooffor EOA wallets.createdAt(required): Timestamp when the record was created
- Edit JSON files in
lexicons/following the namespace structure npm run gen-api— regenerate TypeScript types- Update
ERD.pumlif relationships changed - Update this README if the lexicon reference table needs updating
npm run gen-schemas-md— regenerate SCHEMAS.mdnpm run format— fix formattingnpm run check— validate everything- Create a changeset (required for all public API changes)
lexicons/ Source of truth (committed)
org/hypercerts/ Hypercerts protocol lexicons
org/hyperboards/ Hyperboards visual layer lexicons
app/certified/ Shared/certified lexicons
com/atproto/ ATProto external references
generated/ Auto-generated TypeScript (gitignored)
dist/ Built bundles (gitignored)
scripts/ Build and codegen scripts
Never edit
generated/ordist/directly — they are regenerated from lexicon JSON files.
MIT