{"id":"9377e78b-595a-4ce0-9f95-58613eec9fbc","entityType":"agent","slug":"clawhub-identyclaw-identyclaw","name":"IdentyClaw","canonicalUrl":"https://www.xpersona.co/agent/clawhub-identyclaw-identyclaw","canonicalPath":"/agent/clawhub-identyclaw-identyclaw","generatedAt":"2026-10-10T05:39:00.870Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":null},"description":"IdentyClaw API workflows — multi-API JWT sessions (auto-login), HOLA peer handshake lines, DID resolution, and Passport lookup. Requires an IdentyClaw Passport on the Gateway. Use when calling home or federated APIs, creating or verifying HOLA lines, resolving Passport IDs, or reading agent discovery metadata. For agent-to-agent A2A messaging use the separate identyclaw-a2a plugin.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.9K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s170pyvwn8ckxjt7575svq7r71881627:identyclaw","sourceUrl":"https://clawhub.ai/identyclaw/identyclaw","homepage":"https://clawhub.ai/identyclaw/skills/identyclaw","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/identyclaw/identyclaw","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/identyclaw/skills/identyclaw","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":66,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"IdentyClaw technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":null},"stars":null,"forks":null,"downloads":1911,"packageName":null,"latestVersion":"1.9.6","tractionLabel":"1.9K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T23:05:35.518Z","lastCrawledAt":"2026-10-09T23:05:35.518Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T23:05:35.518Z","lastVerifiedAt":null,"highlights":[{"version":"1.9.6","createdAt":"2026-10-06T17:41:57.689Z","changelog":"v1.9.6: ClawHub skill republish of the 1.9.5 recipient-validation work (1.9.5 was reserved but not promoted on the skill registry). Matching plugin **1.9.6**.","fileCount":19,"zipByteSize":98456},{"version":"1.9.5","createdAt":"2026-10-06T17:30:32.661Z","changelog":"v1.9.5: **`identyclaw_create_hola` / `@rodit/hola-client`:** reject invalid `recipient` values (spaces, slashes, non–Passport-ID strings) at create time with a clear error; tool schema `pattern` + skill docs require `MUNDO` or a 12-letter Passport ID.","fileCount":19,"zipByteSize":98570},{"version":"1.9.4","createdAt":"2026-10-01T07:17:49.179Z","changelog":"v1.9.4: Rebuild / re-pin against OpenClaw Gateway **2026.9.7** (`peerDependencies` / `compat` / `build`).; No runtime API shims; keep `defineToolPlugin` from `openclaw/plugin-sdk/tool-plugin`.; Require Node **≥ 24.16**. Matching ClawHub skill **1.9.4**.","fileCount":19,"zipByteSize":98376},{"version":"1.9.2","createdAt":"2026-09-20T09:25:13.613Z","changelog":"v1.9.2: Mark release ready for OpenClaw gateway **2026.9.5** IdentyClaw template sync (no runtime API changes).","fileCount":19,"zipByteSize":91909},{"version":"1.9.1","createdAt":"2026-08-18T17:55:27.291Z","changelog":"v1.9.1: **Native NEAR account generator:** `identyclaw-generate-near-account` / `identyclaw_generate_near_account` write local-host JSON (`implicit_account_id`, `account_id` alias, `private_key`, `ed25519:` **base58** `public_key`) from 32 bytes of CSPRNG entropy. Compact one-line JSON (mode `0600`) for `NEAR_CREDENTIALS_JSON_B64`. No BIP39 seed phrase (accounts are not for wallet export).; **Docs:** how to enable optional `idcp` and install `near` (near-cli-rs). `idcp` stays off by default (`tools.allow`); native account generation does not need it.; **Observability / config:** log JWT `New-Token` rejections, missing `exp`, and federated claim warnings; require `jwt_token` (no silent `token` fallback); HTTP errors surface API `error.code` / `error.message` without raw bodies; config uses nullish (`??`) resolution and a redacted startup snapshot. `.gitignore` covers `secrets/`; CI runs Gitleaks before install.; **Vocabulary:** say **main** (not production) for the identyclaw-agents deploy tier. Agent workspace `IDENTYCLAW.md` files point at the skill instead of duplicating federated/HOLA workflows.","fileCount":19,"zipByteSize":91996},{"version":"1.9.0","createdAt":"2026-08-18T12:59:18.318Z","changelog":"v1.9.0: **`idcp` tool:** vendored NEAR/RODiT wallet scripts from [openclaw-agents](https://github.com/discernible-io/openclaw-agents) (`idcp-wallet.sh`, `idcp-rotate-passport.sh`, `idcp-activate-account.sh` plus the `idcp-wallet` skill). Agents can list accounts, create/fund implicit accounts, send NEAR, transfer Passport/RODiT on-chain, rotate ownership, and activate credentials. Private keys are never returned (`keys` is refused). Requires `near` (near-cli-rs) on PATH; missing-binary errors include cargo / GitHub-release / `./identyclaw.sh build-image` install steps. Optional tool — allowlist for safer rollout.","fileCount":19,"zipByteSize":91836},{"version":"1.8.4","createdAt":"2026-08-05T09:34:00.965Z","changelog":"v1.8.4: **ClawHub security audit hardening:** exclude publisher `scripts/` from the skill tarball; drop email A2A reference from the skill bundle (A2A remains the separate plugin); fix login timestamp / HOLA checksum doc inconsistencies; replace JWT-shaped examples with placeholders; require checksum-before-install for HTTP `.deb` downloads; add private-key, Passport PII, and autonomous-email warnings.","fileCount":19,"zipByteSize":91292},{"version":"1.8.3","createdAt":"2026-07-23T12:47:49.949Z","changelog":"v1.8.3: **Restore `identyclaw_game_tick` only** (not the full removed `identyclaw_game_*` suite): `ensure_session` → GET `/api/game/tasks` → POST one required `message-report` (defaults 0/0) or `action` (default `none`). Stops observe-only stalls when agents poll `/tasks` but never submit. Join/negotiate still use `identyclaw_request` + peer skill.","fileCount":23,"zipByteSize":96260}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s170pyvwn8ckxjt7575svq7r71881627:identyclaw","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s170pyvwn8ckxjt7575svq7r71881627:identyclaw` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/identyclaw/identyclaw before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T05:39:00.865Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-identyclaw-identyclaw/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":null},"readme":"Skill: IdentyClaw\n\nOwner: identyclaw\n\nSummary: IdentyClaw API workflows — multi-API JWT sessions (auto-login), HOLA peer handshake lines, DID resolution, and Passport lookup. Requires an IdentyClaw Passport on the Gateway. Use when calling home or federated APIs, creating or verifying HOLA lines, resolving Passport IDs, or reading agent discovery metadata. For agent-to-agent A2A messaging use the separate identyclaw-a2a plugin.\n\nTags: latest:1.9.6\n\nVersion history:\n\nv1.9.6 | 2026-10-06T17:41:57.689Z | user\n\nv1.9.6: ClawHub skill republish of the 1.9.5 recipient-validation work (1.9.5 was reserved but not promoted on the skill registry). Matching plugin **1.9.6**.\n\nv1.9.5 | 2026-10-06T17:30:32.661Z | user\n\nv1.9.5: **`identyclaw_create_hola` / `@rodit/hola-client`:** reject invalid `recipient` values (spaces, slashes, non–Passport-ID strings) at create time with a clear error; tool schema `pattern` + skill docs require `MUNDO` or a 12-letter Passport ID.\n\nv1.9.4 | 2026-10-01T07:17:49.179Z | user\n\nv1.9.4: Rebuild / re-pin against OpenClaw Gateway **2026.9.7** (`peerDependencies` / `compat` / `build`).; No runtime API shims; keep `defineToolPlugin` from `openclaw/plugin-sdk/tool-plugin`.; Require Node **≥ 24.16**. Matching ClawHub skill **1.9.4**.\n\nv1.9.2 | 2026-09-20T09:25:13.613Z | user\n\nv1.9.2: Mark release ready for OpenClaw gateway **2026.9.5** IdentyClaw template sync (no runtime API changes).\n\nv1.9.1 | 2026-08-18T17:55:27.291Z | user\n\nv1.9.1: **Native NEAR account generator:** `identyclaw-generate-near-account` / `identyclaw_generate_near_account` write local-host JSON (`implicit_account_id`, `account_id` alias, `private_key`, `ed25519:` **base58** `public_key`) from 32 bytes of CSPRNG entropy. Compact one-line JSON (mode `0600`) for `NEAR_CREDENTIALS_JSON_B64`. No BIP39 seed phrase (accounts are not for wallet export).; **Docs:** how to enable optional `idcp` and install `near` (near-cli-rs). `idcp` stays off by default (`tools.allow`); native account generation does not need it.; **Observability / config:** log JWT `New-Token` rejections, missing `exp`, and federated claim warnings; require `jwt_token` (no silent `token` fallback); HTTP errors surface API `error.code` / `error.message` without raw bodies; config uses nullish (`??`) resolution and a redacted startup snapshot. `.gitignore` covers `secrets/`; CI runs Gitleaks before install.; **Vocabulary:** say **main** (not production) for the identyclaw-agents deploy tier. Agent workspace `IDENTYCLAW.md` files point at the skill instead of duplicating federated/HOLA workflows.\n\nv1.9.0 | 2026-08-18T12:59:18.318Z | user\n\nv1.9.0: **`idcp` tool:** vendored NEAR/RODiT wallet scripts from [openclaw-agents](https://github.com/discernible-io/openclaw-agents) (`idcp-wallet.sh`, `idcp-rotate-passport.sh`, `idcp-activate-account.sh` plus the `idcp-wallet` skill). Agents can list accounts, create/fund implicit accounts, send NEAR, transfer Passport/RODiT on-chain, rotate ownership, and activate credentials. Private keys are never returned (`keys` is refused). Requires `near` (near-cli-rs) on PATH; missing-binary errors include cargo / GitHub-release / `./identyclaw.sh build-image` install steps. Optional tool — allowlist for safer rollout.\n\nv1.8.4 | 2026-08-05T09:34:00.965Z | user\n\nv1.8.4: **ClawHub security audit hardening:** exclude publisher `scripts/` from the skill tarball; drop email A2A reference from the skill bundle (A2A remains the separate plugin); fix login timestamp / HOLA checksum doc inconsistencies; replace JWT-shaped examples with placeholders; require checksum-before-install for HTTP `.deb` downloads; add private-key, Passport PII, and autonomous-email warnings.\n\nv1.8.3 | 2026-07-23T12:47:49.949Z | user\n\nv1.8.3: **Restore `identyclaw_game_tick` only** (not the full removed `identyclaw_game_*` suite): `ensure_session` → GET `/api/game/tasks` → POST one required `message-report` (defaults 0/0) or `action` (default `none`). Stops observe-only stalls when agents poll `/tasks` but never submit. Join/negotiate still use `identyclaw_request` + peer skill.\n\nv1.8.2 | 2026-07-22T18:57:26.968Z | user\n\nv1.8.2: ClawHub skill republish of the 1.8.1 federated-route clarity work (1.8.1 was reserved but not promoted on the registry).\n\nv1.8.1 | 2026-07-22T18:50:39.360Z | user\n\nv1.8.1: **Federated route clarity:** federation shares Rodit login only — peers may expose arbitrary product paths. Skill + tool descriptions no longer teach `identyclaw_get_my_identity` (or other home IdentyClaw routes) against federated hosts.; **`identyclaw_ensure_session`:** when `federated: true`, response includes a `note` steering agents to discover → `identyclaw_request`, and to keep Passport/HOLA/DID tools on `homeBaseUrl`.\n\nv1.6.2 | 2026-07-17T17:00:29.353Z | user\n\nv1.6.2: ClawHub republish of multi-API session support (1.6.0/1.6.1 were reserved but not promoted on the registry).\n\nv1.6.1 | 2026-07-17T16:47:11.362Z | user\n\nv1.6.1: ClawHub republish of the 1.6.0 multi-API session work (registry did not promote 1.6.0 to `latest`).\n\nv1.6.0 | 2026-07-17T16:37:43.882Z | user\n\nv1.6.0: **Multi-API sessions:** JWT cache is keyed per API URL so agents can stay logged into home + federated peers (e.g. `https://api-b.example.com`) at the same time.; **Config:** `apiEndpoints` / `IDENTYCLAW_API_ENDPOINTS` lists known federated hosts; optional `apiEndpoint` on HTTP tools selects the target.; **Tools:** `identyclaw_ensure_session` and `identyclaw_list_sessions` — open/list sessions without exposing JWTs or hand-rolling `POST /api/login`.; **Federated claim check:** soft MITM validation of `rodit_subjectuniqueidentifier_url` / `iss` aligned with `@rodit/rodit-auth-be` ≥9.13.; **Skill / docs:** agents must use plugin tools (not curl login); A2A P2P remains the separate `identyclaw-a2a` plugin.\n\nv1.5.0 | 2026-07-10T18:45:54.644Z | user\n\nv1.5.0: Add `identyclaw_generate_near_account` tool for creating NEAR implicit accounts with allowlisted output directories.\n\nv1.4.0 | 2026-06-09T11:12:21.928Z | user\n\nv1.4.0: Add `skill/` bundle with `skill:sync` and `skill:publish` (ClawHub workflow skill from this repo).; Docs: separate API login (JWT session) from HOLA protocol; align with idclawserver `references/`.; Public-repo polish: MIT-0 license, GitHub Actions CI (`prepare:publish` + mock smoke), updated README and PUBLISH docs.; HOLA client vendored in-repo as `@rodit/hola-client` (replaces `@identyclaw/hola-client` file dependency).; Publish changelog is read from this file; `LICENSE` included in the published package.\n\nv1.2.2 | 2026-06-06T11:21:48.887Z | user\n\nClarify impersonation guard: reject mismatched peerTokenId even when HOLA verification succeeded\n\nv1.2.1 | 2026-06-06T11:05:57.288Z | user\n\nClarify Passport credential vs ClawHub API-key badge; envVar descriptions\n\nv1.1.0 | 2026-06-06T10:23:17.447Z | user\n\nDiscovery index, collaboration envelope, OpenClaw webhook guide; extended reference bundle\n\nArchive index:\n\nArchive v1.9.6: 19 files, 98456 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17899b), references/collaboration-envelope.md (8033b), references/did-rodit-method.md (27764b), references/enrollment.md (32233b), references/finding-agents.md (7067b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2855b), references/login-authentication.md (32323b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8800b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18898b), skill-card.md (2128b), SKILL.md (16751b), _meta.json (129b)\n\nFile v1.9.6:SKILL.md\n\n---\nname: identyclaw\ndescription: >-\n  IdentyClaw API workflows — multi-API JWT sessions (auto-login), HOLA peer\n  handshake lines, DID resolution, and Passport lookup. Requires an IdentyClaw\n  Passport on the Gateway. Use when calling home or federated APIs, creating or\n  verifying HOLA lines, resolving Passport IDs, or reading agent discovery\n  metadata. For agent-to-agent A2A messaging use the separate identyclaw-a2a plugin.\nversion: 1.9.6\nmetadata:\n  openclaw:\n    envVars:\n      - name: IDENTYCLAW_BASE_URL\n        required: false\n        description: Home API base URL (default https://api.identyclaw.com)\n      - name: IDENTYCLAW_API_ENDPOINTS\n        required: false\n        description: Comma-separated federated API URLs for concurrent sessions (e.g. https://api-b.example.com)\n      - name: IDENTYCLAW_ACCOUNT_ID\n        required: false\n        description: NEAR implicit account id (64-char hex) for API login\n      - name: IDENTYCLAW_NEAR_PRIVATE_KEY\n        required: false\n        description: Passport Ed25519 key (ed25519:...) — API login signature + HOLA line signing (Gateway only)\n    homepage: https://api.identyclaw.com/docs\n---\n\n# IdentyClaw\n\n**Home API (default):** `https://api.identyclaw.com`  \n**Federated example:** `https://api-b.example.com` (same Rodit login family; configure via `apiEndpoints`)\n\nIdentyClaw is an HTTP API for IdentyClaw Passport holders and the **HOLA** mutual authentication protocol. This skill is a **convenience cheat sheet** for agents; tool catalog and install steps live in the plugin [README](https://github.com/discernible-io/openclaw-identyclaw-plugin/blob/main/README.md). Deep specs live in bundled `references/` and MCP `doc:*` resources.\n\n> **Convenience document:** Change the plugin README and MCP `doc:*` resources first; update this skill only to keep the walkthrough accurate.\n\n**Live docs:** MCP `doc:discovery` · `doc:skills` · `curl https://api.identyclaw.com/api/mcp/resource/doc:skills`\n\n**ClawHub:** [identyclaw/identyclaw](https://clawhub.ai/identyclaw/identyclaw) · [OpenClaw plugin](https://clawhub.ai/plugins/@identyclaw/openclaw-identyclaw-plugin) · [Source (skill + plugin)](https://github.com/discernible-io/openclaw-identyclaw-plugin)\n\n---\n\n## Home vs federated — do not assume shared routes\n\nFederation shares **Rodit login** only (`GET /api/login/timestamp` → sign → `POST /api/login` → JWT cached per URL). A federated peer may expose **any** product routes. It does **not** inherit the home IdentyClaw surface (`/api/me/identity`, HOLA, DID, `/api/agents`, …).\n\n| Target | What to call |\n| --- | --- |\n| **Home** (`baseUrl`, omit `apiEndpoint`) | Passport/HOLA/DID tools: `identyclaw_get_my_identity`, `identyclaw_create_hola`, `identyclaw_verify_hola`, `identyclaw_get_agent_identity`, `identyclaw_resolve_did`, … |\n| **Federated peer** (`apiEndpoint=…`) | `identyclaw_ensure_session` → **discover** (`identyclaw_list_resources` / `identyclaw_get_resource` / peer skill.md / OpenAPI) → **product calls** via `identyclaw_request({ method, path, apiEndpoint })` |\n\n**Never** probe home-only tools against a federated host “to see if they work.” A 404 on `/api/me/identity` is expected when that peer does not implement it — not a login failure.\n\n---\n\n## Agent rule — do not hand-roll login\n\nWhen the **OpenClaw plugin** is installed (`identyclaw-tools`):\n\n1. **Never** curl `GET /api/login/timestamp` or `POST /api/login`, and never invent Ed25519 signatures in chat.\n2. Call **`identyclaw_ensure_session`** (optional `apiEndpoint`) — the plugin auto-logins and caches a **JWT per API URL**.\n3. **Home tools stay on home:** omit `apiEndpoint` for Passport/HOLA/DID helpers unless you already know that host implements those IdentyClaw paths.\n4. **Federated product work:** after `ensure_session`, discover that peer’s routes, then call them with **`identyclaw_request`** — do not reuse home tool paths.\n5. Use **`identyclaw_list_sessions`** to see which APIs already have a live session.\n6. **A2A P2P** (message another agent over `/a2a`) is **not** this plugin — install/use **`identyclaw-a2a`**. That plugin owns per-peer JWTs.\n\nManual curl login below is for **operators / non-plugin clients only**.\n\n---\n\n## Two lanes — do not mix them\n\n| Lane | Artifact | Typical TTL | Signing | Docs |\n| --- | --- | --- | --- | --- |\n| **API login** | Bearer **JWT** (`jwt_token`) | ~1 hour | `accountid` + `timestamp_iso` → **base64url** | [`references/login-authentication.md`](references/login-authentication.md) |\n| **HOLA protocol** | **HOLA line** (slash-separated string) | ~5 min (nonce) | Canonical prefix → **base32** + checksum | [`references/hola-howto.md`](references/hola-howto.md), [`references/hola-agent-authentication.md`](references/hola-agent-authentication.md) |\n\n**Two clocks:**\n\n| Clock | Source | Used for |\n| --- | --- | --- |\n| JWT **session** | `POST /api/login` (plugin auto) | `Authorization: Bearer …` on protected routes |\n| HOLA **nonce** | `GET /api/holanonce16ts` | `noncetsHex` + `timestamp` in each HOLA line — **not** login `timestamp_iso` |\n\n| Endpoint | JSON fields | Purpose |\n| --- | --- | --- |\n| `GET /api/login/timestamp` | `timestamp`, `timestamp_iso` | API login only |\n| `GET /api/holanonce16ts` | `noncetsHex`, `timestamp` | HOLA line only — [`references/holanonce-api.md`](references/holanonce-api.md) |\n\nA JWT is **not** a HOLA line. HOLA tools need an API session to call protected routes; the handshake payload is the **HOLA wire string**.\n\n---\n\n## Credentials (ClawHub “API key required” badge)\n\nClawHub’s badge means your **IdentyClaw Passport** — not a separate vendor API key.\n\n| What you configure | Role |\n| --- | --- |\n| **Passport signing key** (`accountid` + `nearPrivateKey`) | Long-lived secret on the Gateway (like an API key) |\n| **JWT** (`jwt_token`) | Short-lived **API session**; plugin auto-login supplies this (never paste into chat) |\n| **Public routes** | No Passport needed |\n\n**`nearPrivateKey` on the Gateway** — same NEAR key, **two signatures**:\n\n1. **API login** — base64url over `accountid` + `timestamp_iso`\n2. **HOLA create** — base32 over uppercase canonical HOLA prefix (`identyclaw_create_hola` / `@rodit/hola-client`)\n\n`identyclaw_verify_hola` needs only API session + peer HOLA line (no `nearPrivateKey`).\n\n```json5\n{\n  plugins: {\n    entries: {\n      \"identyclaw-tools\": {\n        enabled: true,\n        config: {\n          baseUrl: \"https://api.identyclaw.com\",\n          apiEndpoints: [\"https://api-b.example.com\"],\n          accountid: \"<64-char-hex-near-implicit-account>\",\n          nearPrivateKey: \"ed25519:...\"\n        }\n      }\n    }\n  }\n}\n```\n\nEnv alternative: `IDENTYCLAW_API_ENDPOINTS=https://api-b.example.com`.\n\nEnroll first if needed: [`references/login-authentication.md`](references/login-authentication.md). Never paste keys or JWTs into chat.\n\n**Security notes (operators):**\n- Prefer the OpenClaw plugin for login/HOLA so private keys and JWTs stay on the Gateway.\n- Passport metadata (DN, ContactURI, geo, facial fields) is sensitive — minimize logging and collection.\n- Agent-to-agent A2A is **not** this skill — use `identyclaw-a2a` / the A2A trust skill. Do not enable autonomous email from this skill’s docs.\n\n---\n\n## Install and entry points\n\n```text\nSkill (workflows):     openclaw skills install clawhub:identyclaw\nPlugin (API + HOLA):   openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\nPlugin (A2A P2P):      openclaw plugins install clawhub:@identyclaw/openclaw-a2a-plugin\nMCP (docs):            https://api.identyclaw.com/mcp\nDiscovery index:       doc:discovery\nCheat sheet:           doc:skills\n```\n\n---\n\n## Agent cheat sheet\n\n| # | Goal | Method | Lane |\n|---|------|--------|------|\n| 1 | API session (home or federated) | `identyclaw_ensure_session` ± `apiEndpoint` | API login |\n| 2 | List live sessions | `identyclaw_list_sessions` | API login |\n| 3 | Discover federated peer routes | `identyclaw_list_resources` / `get_resource` / peer skill + `identyclaw_request` | Federated product |\n| 4 | **Create outbound HOLA line** | `identyclaw_create_hola` (home) | HOLA (+ home session) |\n| 5 | **Verify peer HOLA line** | `identyclaw_verify_hola` (home) | HOLA (+ home session) |\n| 6 | Resolve Passport → full DN | `identyclaw_get_agent_identity` (home) | Home API session |\n| 7 | List public agents | `identyclaw_list_agents` (home) | Public |\n| 8 | Resolve DID | `identyclaw_resolve_did` (home) | Home API session |\n| 9 | Message another agent (A2A) | **`identyclaw-a2a` plugin** (not this skill’s HTTP tools) | A2A P2P |\n| 10 | List / transfer RODiT on-chain | **`idcp`** (`list`, `transfer`, `rotate`, …) | NEAR / RODiT |\n\n### 1. API session (plugin — preferred)\n\n```text\n# Home identity / HOLA / DID\nidentyclaw_ensure_session\nidentyclaw_get_my_identity\nidentyclaw_list_sessions\n\n# Federated peer — login + discover + product routes (arbitrary paths)\nidentyclaw_ensure_session   apiEndpoint=https://api-b.example.com\nidentyclaw_list_resources   apiEndpoint=https://api-b.example.com\nidentyclaw_get_resource     uri=doc:discovery  apiEndpoint=https://api-b.example.com\nidentyclaw_request          method=GET path=/…  apiEndpoint=https://api-b.example.com\n```\n\nSessions are **cached per URL**. You can be logged into home and federated APIs **at the same time**. Federated login does **not** mean the peer implements home IdentyClaw routes.\n\n### 1b. Manual API login (operators / non-plugin only)\n\n```bash\nBASE=https://api.identyclaw.com   # or federated peer URL\n\nTS_JSON=$(curl -sS \"$BASE/api/login/timestamp\")\nTIMESTAMP=$(echo \"$TS_JSON\" | jq -r '.timestamp')\nTIMESTAMP_ISO=$(echo \"$TS_JSON\" | jq -r '.timestamp_iso')\n\n# Sign UTF-8: <accountid> + <timestamp_iso> (no separator) → base64url_signature\n\nJWT=$(curl -sS -X POST \"$BASE/api/login\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"{\\\"accountid\\\":\\\"<64-char-hex>\\\",\\\"timestamp\\\":$TIMESTAMP,\\\"base64url_signature\\\":\\\"<sig>\\\"}\" \\\n  | jq -r '.jwt_token')\n```\n\nFull steps: [`references/login-authentication.md`](references/login-authentication.md#quick-start-login-pattern).\n\n### 2. Create outbound HOLA line\n\n**Recommended:** `identyclaw_create_hola` (plugin **v1.4.0+**) — API session fetches nonce; **private key signs HOLA locally**.\n\n```text\nHOLA/<recipient>/<tokenId>/<timestamp>/<noncetsHex>/API.IDENTYCLAW.COM/<base32-signature>/<checksum>\n```\n\n**Outbound HOLA rules (agents):**\n\n- **Signer / origin** is always **this agent's Passport ID** — resolved from `GET /api/me/identity`.\n- Call **`identyclaw_create_hola`** without `tokenId`, or call **`identyclaw_get_my_identity`** first if you need your ID for other steps.\n- **Never ask the user for your own Passport ID** to create an outbound HOLA line.\n- **Only `recipient`** may be user-supplied: peer **12-letter Passport ID** (letters only, **no spaces** — e.g. `BKBVEHBDCRGM`) or `MUNDO` for broadcast intros. Do not pass display names or space-separated strings; invalid recipients are rejected before signing.\n- **Subagent delegation** uses a different HOLA wire format — see [`references/hola-subagent-authentication.md`](references/hola-subagent-authentication.md); do not substitute another agent's ID in standard outbound HOLA.\n\nWalkthrough: [`references/hola-howto.md`](references/hola-howto.md). Self-test: `POST /api/testhola`.\n\n### 3. Verify an incoming HOLA line\n\nUse **`identyclaw_verify_hola`** with the exact HOLA string. The JWT only authorizes the API call.\n\nTrust only when `verified: true`. Diagnostics: [`references/hola-agent-authentication.md`](references/hola-agent-authentication.md#verification-result-diagnostics-apidentityverify).\n\n### 4–8. Identity, discovery, DID (home API)\n\nPrefer plugin tools on the **home** `baseUrl` (`identyclaw_get_agent_identity`, `identyclaw_list_agents`, `identyclaw_resolve_did`). Only pass `apiEndpoint` when you already know that host implements the same IdentyClaw path.\n\n---\n\n## First contact from an unknown agent\n\n1. **Home API session** — `identyclaw_ensure_session` (do not curl login).\n2. **Verify HOLA line** — `identyclaw_verify_hola` with the exact string received (not a JWT).\n3. **If `verified: true`** — note `peerTokenId`.\n4. **Lookup** — `identyclaw_get_agent_identity` (home).\n5. **Impersonation guard** — compare `peerTokenId` to officially published Passport ID. [`references/finding-agents.md`](references/finding-agents.md#5-guard-against-impersonation).\n6. **Subagent** — `identyclaw_check_subagent_signer` when delegation fields present. [`references/hola-subagent-authentication.md`](references/hola-subagent-authentication.md).\n7. **Ongoing messaging** — use **A2A** (`identyclaw-a2a`), not repeated HOLA for every turn.\n\n---\n\n## OpenClaw plugin (recommended for Gateways)\n\n```bash\nopenclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\n```\n\nPlugin **v1.6.0+** · tool reference: [README.md](https://github.com/discernible-io/openclaw-identyclaw-plugin/blob/main/README.md)\n\n### Session tools\n\n| Tool | Role |\n| --- | --- |\n| `identyclaw_ensure_session` | Open/refresh session for home or `apiEndpoint` (no JWT returned). Federated responses include a discover-then-`identyclaw_request` hint. |\n| `identyclaw_list_sessions` | List cached multi-API sessions |\n\n### Discovery / generic HTTP (safe on federated peers)\n\n| Tool | Role |\n| --- | --- |\n| `identyclaw_list_resources` | `GET /api/mcp/resources` — if the peer exposes MCP docs |\n| `identyclaw_get_resource` | `GET /api/mcp/resource/{uri}` |\n| `identyclaw_request` | Arbitrary `method` + `path` on home or federated host |\n| `identyclaw_game_tick` | SLC only: ensure session + submit one required message-report/action (safe defaults). Prefer over multi-step `identyclaw_request` for required submits — do not only poll `/tasks`. Pass `apiEndpoint` for the game host. |\n| `idcp` | On-chain RODiT / Passport wallet (near-cli-rs). Actions: `list`, `genaccount`, `summary`, `init`, `send_near`, `transfer`, `rotate`, `activate`. **Off by default** — add `\"idcp\"` to `tools.allow` and install `near` (near-cli-rs) on the gateway PATH, then restart. Never returns private keys. Native `identyclaw_generate_near_account` does not need this. |\n\n### Home IdentyClaw surface (default: omit `apiEndpoint`)\n\n| Tool | Endpoint |\n| --- | --- |\n| `identyclaw_list_agents` | `GET /api/agents` |\n| `identyclaw_get_my_identity` | `GET /api/me/identity` |\n| `identyclaw_get_agent_identity` | `GET /api/identity/token/{tokenId}/full` |\n| `identyclaw_check_subagent_signer` | `POST /api/isauthorizedsigner` |\n| `identyclaw_resolve_did` | `GET /.well-known/did/resolve` |\n| `identyclaw_get_nonce` | `GET /api/holanonce16ts` |\n| `identyclaw_create_hola` | local HOLA sign; signer from `/api/me/identity` |\n| `identyclaw_verify_hola` | `POST /api/identity/verify` |\n\nThese home-surface tools still accept `apiEndpoint` for rare full IdentyClaw replicas — **do not** pass a federated product host unless you know it implements that path. Allowlist optional tools in `tools.allow` when credentials are configured. Enable `idcp` only when on-chain wallet actions are required (`near` on PATH).\n\n**ClawHub skill (this bundle):** `openclaw skills install clawhub:identyclaw`\n\n---\n\n## Bundled references\n\n| Topic | File |\n|-------|------|\n| Endpoint catalog | [`references/api-reference.md`](references/api-reference.md) |\n| API login / JWT | [`references/login-authentication.md`](references/login-authentication.md) |\n| HOLA quick path | [`references/hola-howto.md`](references/hola-howto.md) |\n| HOLA full spec | [`references/hola-agent-authentication.md`](references/hola-agent-authentication.md) |\n| HOLA nonce JSON | [`references/holanonce-api.md`](references/holanonce-api.md) |\n| Subagent delegation | [`references/hola-subagent-authentication.md`](references/hola-subagent-authentication.md) |\n| Agent discovery | [`references/finding-agents.md`](references/finding-agents.md) |\n| Collaboration envelope | [`references/collaboration-envelope.md`](references/collaboration-envelope.md) |\n| OpenClaw webhooks | [`references/openclaw-integration-guide.md`](references/openclaw-integration-guide.md) |\n| Client-side auth | [`references/mcp-auth-tools.md`](references/mcp-auth-tools.md) |\n| Enrollment | [`references/enrollment.md`](references/enrollment.md) |\n\n---\n\n## Conventions\n\n**Terminology:** User-facing copy says **IdentyClaw Passport** (12-letter ID). **RODiT** is protocol technology only — do not say \"RODiT Passport.\"\n\n**Skill vs plugin vs MCP vs A2A:** This **skill** teaches workflows. The **identyclaw-tools** plugin runs multi-API login, HOLA, and identity. **MCP** serves documentation. **identyclaw-a2a** owns agent-to-agent P2P JWTs.\n\nFile v1.9.6:README.md\n\n# IdentyClaw ClawHub skill\n\nWorkflow skill for OpenClaw agents. Published separately from the code plugin on ClawHub (`clawhub:identyclaw`).\n\n## Layout\n\n```text\nskill/\n├── SKILL.md              # ClawHub publish source (version in frontmatter)\n├── references/           # gitignored — populated by skill:sync\n└── scripts/\n    ├── sync-references.mjs\n    └── publish-clawhub.mjs\n```\n\nReference docs are copied from **idclawserver-idc** at publish time (canonical API specs). Default path: `../idclawserver-idc/references`.\n\n## Development\n\nFrom repository root:\n\n```bash\nnpm run skill:sync\nnpm run skill:publish:dry-run\nnpm run skill:publish\n```\n\nOverride references source:\n\n```bash\nIDENTYCLAW_REFERENCES=/path/to/idclawserver-idc/references npm run skill:sync\n```\n\n## ClawHub\n\n- Skill: `openclaw skills install clawhub:identyclaw`\n- Plugin: `openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin`\n\nSee [PUBLISH.md](./PUBLISH.md) and root [PUBLISH.md](../PUBLISH.md) for ClawHub auth.\n\nFile v1.9.6:_meta.json\n\n{\n  \"ownerId\": \"kn7ev9fw0fs1g0z9r4wt5bg5bh86bmj7\",\n  \"slug\": \"identyclaw\",\n  \"version\": \"1.9.6\",\n  \"publishedAt\": 1791308517689\n}\n\nFile v1.9.6:references/api-reference.md\n\n# API Reference\n\nComplete endpoint listing for IdentyClaw API.\n\n## Table of Contents\n\n- [Public Endpoints](#public-endpoints)\n- [Protected Endpoints](#protected-endpoints)\n- [Privileged Endpoints](#privileged-endpoints)\n- [DID Resolution](#did-resolution)\n- [MCP Resources](#mcp-resources)\n- [Policy Documents](#policy-documents)\n\n## Public Endpoints\n\nNo authentication required.\n\n### Discovery\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/` | GET | API overview with enrollment URL and endpoint listing |\n| `/health` | GET | Health check endpoint |\n| `/.well-known/enrollment` | GET | Complete enrollment guide with pricing and steps |\n| `/.well-known/mcp` | GET | MCP discovery metadata — see [mcp-connection-guide.md](mcp-connection-guide.md) |\n| `/openapi.json` | GET | Canonical OpenAPI 3.0 specification |\n| `/swagger.json` | GET | OpenAPI 3.0 specification (alias of `/openapi.json`) |\n| `/api/v1/openapi.json` | GET | Deprecated redirect to `/openapi.json` |\n| `/docs/enrollment` | GET | **Removed** — always returns `410 ENDPOINT_REMOVED` |\n| `/api-docs` | * | **Removed** — always returns `410 ENDPOINT_REMOVED` |\n\n### Authentication\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/login/timestamp` | GET | Get single-use timestamp challenge pair for login |\n| `/api/login` | POST | Authenticate with accountid signature and fresh challenge, get JWT |\n\nLogin request/response shapes, field constraints, and error semantics are maintained in OpenAPI:\n\n- Canonical contract: [`../api-docs/swagger.json`](../../api-docs/swagger.json)\n- Runtime endpoints: `GET /openapi.json`, `GET /swagger.json`\n\nFor step-by-step API login implementation guidance (challenge retrieval, signing flow, retries, and troubleshooting), use:\n\n- [`login-authentication.md`](login-authentication.md)\n\n### Agent Discovery\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/agents` | GET | List all IdentyClaw Passport holders (cursor-paginated) |\n\n**Query Parameters**:\n- `limit` (default: 20, max: 100)\n- `cursor` (optional, for pagination)\n\n**Response**:\n```json\n{\n  \"agents\": [\n    {\n      \"tokenId\": \"bkbvehbdcrgm\",\n      \"creature\": \"Legal Specialist\",\n      \"face\": {\n        \"checksumValid\": true,\n        \"categories\": {\n          \"skinTone\": { \"index\": 2, \"letter\": \"c\", \"value\": \"pale-skinned\" },\n          \"ethnicity\": { \"index\": 1, \"letter\": \"b\", \"value\": \"Nordic\" },\n          \"faceShape\": { \"index\": 0, \"letter\": \"a\", \"value\": \"oval-faced\" }\n        }\n      }\n    }\n  ],\n  \"nextCursor\": \"cursor_string_or_null\",\n  \"requestId\": \"01HQXYZ...\",\n  \"disclaimer\": \"The creature field and other agent metadata are self-declared by the agent. It is your responsibility to verify the accuracy and authenticity of this information before relying on it.\"\n}\n```\n\n### Client Token Signing\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/signclient` | POST | Request server to sign client token metadata |\n\n**Note**: Request non-privileged signing operations through this endpoint. Use permissioned metrics/system/debug/reset endpoints for privileged flows.\n\n### Identity Verification\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/identity/verify` | POST | Verify peer HOLA message (public; optional JWT for `RECIPIENT_MISMATCH`; edge rate-limited) |\n\n**POST /api/identity/verify**:\n\nVerify a HOLA message from a peer agent. No authentication required. When a bearer JWT is supplied, the caller's authenticated identity is used for `RECIPIENT_MISMATCH` warnings (suppress with `expectedRecipient`).\n\n**Request**:\n```json\n{\n  \"hola\": \"HOLA/MUNDO/bkbvehbdcrgm/2026-04-19T10:47:00.000Z/4F9A3C7E.../API.IDENTYCLAW.COM/dGVzdA.../M\"\n}\n```\n\n**Response** (HTTP 200 when well-formed — trust only when `verified` is true):\n```json\n{\n  \"verified\": true,\n  \"peerTokenId\": \"bkbvehbdcrgm\",\n  \"destinatary\": \"MUNDO\",\n  \"checks\": {\n    \"tokenExists\": true,\n    \"tokenActive\": true,\n    \"timestampFresh\": true,\n    \"nonceReplaySafe\": true,\n    \"signatureValid\": true,\n    \"checksumValid\": true\n  },\n  \"failureReasons\": [],\n  \"requestId\": \"01HQXYZ...\"\n}\n```\n\nSee [hola-agent-authentication.md](hola-agent-authentication.md) for full diagnostics.\n\n---\n\n## Protected Endpoints\n\nRequire JWT authentication via `Authorization: Bearer <token>` header.\n\n### Identity\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/me/identity` | GET | Get your own identity information |\n| `/api/identity/token/{tokenId}/full` | GET | Get full identity metadata for any token |\n| `/api/isauthorizedsigner` | POST | Check if caller is authorized to sign |\n\n**GET /api/identity/token/{tokenId}/full**:\n\nReturns complete identity metadata including DN attributes, facial description, and peer-routable `metadata.webhook_url` when set on-chain.\n\n**Response**:\n```json\n{\n  \"tokenId\": \"bkbvehbdcrgm\",\n  \"dn\": {\n    \"raw\": \"NNSWF=Alice,Creature=Legal Specialist,Address=123 Main St\",\n    \"nameNotSharedWithFamily\": \"Alice\",\n    \"nameSharedWithFamily\": \"Smith\",\n    \"displayName\": \"Alice Smith\",\n    \"contactUri\": \"alice@example.com\",\n    \"taxResidence\": \"US\",\n    \"inceptDateTime\": \"2026-01-01T00:00:00.000Z\",\n    \"inceptPlace\": \"New York\",\n    \"taxPayerCode\": \"12-3456789\",\n    \"address\": \"123 Main St\",\n    \"creature\": \"Legal Specialist\",\n    \"avatarUrl\": \"https://example.com/avatar.jpg\",\n    \"emojiUrl\": \"https://example.com/emoji.png\",\n    \"allAttributes\": {}\n  },\n  \"face\": {\n    \"checksumValid\": true,\n    \"categories\": {\n      \"skinTone\": { \"index\": 2, \"letter\": \"c\", \"value\": \"pale-skinned\" },\n      \"ethnicity\": { \"index\": 1, \"letter\": \"b\", \"value\": \"Nordic\" },\n      \"faceShape\": { \"index\": 0, \"letter\": \"a\", \"value\": \"oval-faced\" }\n    }\n  },\n  \"metadata\": {\n    \"webhook_url\": \"https://my-openclaw.example.com\"\n  },\n  \"requestId\": \"01HQXYZ...\",\n  \"disclaimer\": \"The DN metadata including creature, name, contact URI, address, and other attributes are self-declared by the agent. It is your responsibility to verify the accuracy and authenticity of this information before relying on it.\"\n}\n```\n\n### Nonces\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/holanonce16ts` | GET | Get nonce for HOLA message (16-byte nonce); requires Bearer JWT |\n\n**Exact response JSON keys** (use verbatim; not login `timestamp_iso` / not `nonceHex`): `noncetsHex`, `timestamp`, `length`, `algorithm`, `requestId`. See [holanonce-api.md](holanonce-api.md).\n\n**Response**:\n```json\n{\n  \"noncetsHex\": \"4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE\",\n  \"timestamp\": \"2026-04-19T10:47:00.000Z\",\n  \"length\": 16,\n  \"algorithm\": \"randomBytes(16)_hex\",\n  \"requestId\": \"01HQXYZ...\"\n}\n```\n\n### Session Management\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/logout` | POST | Logout and invalidate JWT token |\n\n### HOLA Self-Test\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/testhola` | POST | Validate **your own** outbound HOLA before sending to peers (JWT required; not permission-gated) |\n\n**POST /api/testhola**:\n\nSelf-testing endpoint — submit a complete HOLA line you generated. On success the server returns its own valid HOLA response. For verifying **another agent's** HOLA, use public `POST /api/identity/verify` instead.\n\n**Request**:\n```json\n{\n  \"hola\": \"HOLA/MUNDO/bkbvehbdcrgm/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/MFRGG.../J\"\n}\n```\n\nOptional: `expectedRecipient` — suppresses `RECIPIENT_MISMATCH` when the HOLA recipient does not match your authenticated Passport ID.\n\n**Response** (HTTP 200 when valid):\n```json\n{\n  \"valid\": true,\n  \"peerTokenId\": \"bkbvehbdcrgm\",\n  \"destinatary\": \"MUNDO\",\n  \"peerVerified\": true,\n  \"hola\": \"HOLA/MUNDO/<serverTokenId>/.../API.IDENTYCLAW.COM/.../X\",\n  \"serverTokenId\": \"pkcnjdbdefcp\",\n  \"checks\": {\n    \"formatValid\": true,\n    \"checksumValid\": true,\n    \"timestampFresh\": true,\n    \"nonceReplaySafe\": true,\n    \"signatureValid\": true\n  },\n  \"requestId\": \"01HQXYZ...\"\n}\n```\n\nInvalid payloads return HTTP 400 with `code: HOLA_VALIDATION_FAILED` and `error.details.reasonCode`.\n\n---\n\n## Privileged Endpoints\n\nRequire JWT authentication AND specific permissions in IdentyClaw Passport's `permissioned_routes`.\n\n### Metrics\n\n| Endpoint | Method | Description | Permission Required |\n|----------|--------|-------------|---------------------|\n| `/api/metrics` | GET | Get performance metrics (admin only) | `metrics` |\n| `/api/metrics/system` | GET | Get system metrics (admin only) | `system` |\n| `/api/metrics/reset` | POST | Reset metrics | `reset` |\n| `/api/metrics/debug` | GET | Get debug information | `debug` |\n\n### Sessions\n\n| Endpoint | Method | Description | Permission Required |\n|----------|--------|-------------|---------------------|\n| `/api/sessions/list_all` | GET | List all active sessions | `list_all` |\n| `/api/sessions/cleanup` | POST | Cleanup expired sessions | `cleanup` |\n| `/api/sessions/revoke` | POST | Revoke specific session | `revoke` |\n\n---\n\n## DID Resolution\n\n**Status:** Experimental HTTP resolver (OpenAPI). **Method specification:** [did-rodit-method.md](did-rodit-method.md) (public: `GET /.well-known/did-method-rodit`). **W3C registry:** [did-method-registry-submission.md](did-method-registry-submission.md).\n\nProtected endpoints for DID resolution (require JWT authentication). Primary identifier: `did:rodit:<12-letter-passport-id>`. Alias: `did:web:<host>:token:<passport-id>`. Resolution uses the server’s `NEAR_CONTRACT_ID` on NEAR mainnet.\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/.well-known/did/rodit/{tokenId}` | GET | Get DID document for IdentyClaw Passport |\n| `/.well-known/did/resolve` | GET | Resolve DID from token ID (query param: `did`) |\n| `/.well-known/did/web/token/{tokenId}` | GET | Get DID:web document |\n| `/.well-known/did/web/token/{tokenId}/did.json` | GET | Get DID:web JSON document |\n\n**Example** (`GET /.well-known/did/resolve?did=did:rodit:bkbvehbdcrgm`):\n\nSee [did-rodit-method.md §5](did-rodit-method.md#5-did-document) for the full document shape. Illustrative fields:\n\n```json\n{\n  \"id\": \"did:rodit:bkbvehbdcrgm\",\n  \"alsoKnownAs\": [\n    \"did:web:api.identyclaw.com:token:bkbvehbdcrgm\"\n  ],\n  \"controller\": \"<near-owner-account-id>\",\n  \"verificationMethod\": [\n    {\n      \"id\": \"did:rodit:bkbvehbdcrgm#controller\",\n      \"type\": \"Ed25519VerificationKey2020\",\n      \"publicKeyBase58\": \"...\"\n    }\n  ],\n  \"authentication\": [\n    \"did:rodit:bkbvehbdcrgm#controller\"\n  ],\n  \"service\": [\n    \"RoditTokenMetadata\",\n    \"MCPDiscoveryService\"\n  ]\n}\n```\n\n---\n\n## MCP Resources\n\nMachine-readable capabilities for AI agent discovery (public endpoints).\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/mcp/resources` | GET | List all available MCP resources |\n| `/api/mcp/resource/{uri}` | GET | Get specific MCP resource by URI |\n| `/api/mcp/schema` | GET | Get MCP schema definition |\n\n### MCP Streamable HTTP Transport\n\nDistinct from REST discovery above — requires an MCP client (not plain `curl` for docs). See [mcp-connection-guide.md](mcp-connection-guide.md).\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/mcp` | GET | SSE stream for an established MCP session (`Accept: text/event-stream`) |\n| `/mcp` | POST | JSON-RPC MCP requests (`Accept: application/json, text/event-stream`) |\n| `/mcp` | DELETE | Terminate an MCP transport session |\n\n---\n\n**GET /api/mcp/resources**:\n\nLists all available MCP resources for AI agent integration.\n\n**Response**:\n```json\n{\n  \"resources\": [\n    {\n      \"uri\": \"jsonld:context\",\n      \"name\": \"JSON-LD Context\",\n      \"description\": \"JSON-LD context for semantic mappings\",\n      \"mimeType\": \"application/ld+json\"\n    },\n    {\n      \"uri\": \"jsonld:contract-metadata\",\n      \"name\": \"Contract Metadata\",\n      \"description\": \"Contract metadata as JSON-LD\",\n      \"mimeType\": \"application/ld+json\"\n    },\n    {\n      \"uri\": \"howto:enrollment\",\n      \"name\": \"Enrollment Guide\",\n      \"description\": \"Complete enrollment guide with pricing\",\n      \"mimeType\": \"text/markdown\"\n    },\n    {\n      \"uri\": \"howto:authentication\",\n      \"name\": \"Authentication Flows\",\n      \"description\": \"API login and HOLA protocol flows\",\n      \"mimeType\": \"text/markdown\"\n    },\n    {\n      \"uri\": \"howto:hola-protocol\",\n      \"name\": \"HOLA Protocol\",\n      \"description\": \"HOLA protocol specification\",\n      \"mimeType\": \"text/markdown\"\n    }\n  ],\n  \"requestId\": \"01HQXYZ...\"\n}\n```\n\n**GET /api/mcp/resource/{uri}**:\n\nRetrieve a specific MCP resource by URI.\n\n**Example**: `GET /api/mcp/resource/jsonld:context`\n\n**Response**: Returns the resource content (format varies by resource type)\n\n---\n\n## Policy Documents\n\nPublic policy documents (no authentication required).\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/.well-known/terms-of-service` | GET | Terms of Service |\n| `/.well-known/privacy-policy` | GET | Privacy Policy |\n| `/.well-known/data-retention` | GET | Data Retention Policy |\n| `/.well-known/why-identyclaw` | GET | Use cases and benefits of IdentyClaw |\n| `/.well-known/did-method-rodit` | GET | Canonical `did:rodit` DID method specification (Markdown) |\n\n---\n\n## Rate Limiting\n\nTwo layers apply:\n\n| Layer | Scope | Mechanism |\n|-------|-------|-----------|\n| **Edge (public routes)** | Selected public URIs (e.g. `/api/login/timestamp`, `/api/identity/verify`, `/api/agents`) | nginx `limit_req` per `$remote_addr` — see OpenAPI `info.x-publicRateLimit` (1101 req/min sustained, burst 6101) |\n| **Authenticated routes** | Protected/privileged routes after JWT login | Per-Passport `max_requests` / `maxrq_window` from on-chain metadata via SDK rate limiter |\n\nThe API does **not** emit `X-RateLimit-*` headers. Rate-limit failures use the standard error envelope:\n\n**Response** (HTTP 429, public edge example):\n```json\n{\n  \"error\": {\n    \"code\": \"RATE_LIMIT_EXCEEDED\",\n    \"message\": \"Exceeded anonymous auth-params rate limit\"\n  },\n  \"requestId\": \"01HX9WZ7F7B5DDXPKRZC4J8M0X\",\n  \"timestamp\": \"2026-04-15T08:20:00.000Z\"\n}\n```\n\n---\n\n## Error Codes\n\nCommon error codes across all endpoints:\n\n| Code | Status | Description |\n|------|--------|-------------|\n| `UNAUTHORIZED` | 401 | Missing or invalid JWT token |\n| `FORBIDDEN` | 403 | Insufficient permissions |\n| `NOT_FOUND` | 404 | Resource not found |\n| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests |\n| `INTERNAL_SERVER_ERROR` | 500 | Server error |\n\n### Authentication Errors\n\n| Code | Status | Description |\n|------|--------|-------------|\n| `SIGNATURE_VERIFICATION_FAILED_035` | 401 | Signature verification failed |\n| `TOKEN_EXPIRED` | 401 | IdentyClaw Passport expired |\n| `TOKEN_NOT_FOUND` | 404 | IdentyClaw Passport not found |\n| `INVALID_TOKEN_ID` | 400 | Invalid token ID format |\n\n### HOLA Errors\n\nHTTP failures from `/api/testhola` and early validation on `/api/identity/verify` use these **`error.code`** values (HOLA lane — **base32** line signature, **HOLA nonce** from `GET /api/holanonce16ts`, ISO timestamp from that nonce response in the line):\n\n| Code | Status | Description |\n|------|--------|-------------|\n| `HOLA_VALIDATION_FAILED` | 400 | Shape, envelope, transport lint, format, fields, token id, nonce hex, checksum, etc. Use `error.details.reasonCode` for the specific fault. |\n| `HOLA_TIMESTAMP_INVALID` | 400 | HOLA line timestamp not valid ISO-8601, or outside allowed freshness window on `/api/testhola`. |\n| `HOLA_SIGNATURE_INVALID` | 400 | HOLA line signature verification failed on `/api/testhola`; peer verify often returns HTTP 200 with `failureReasons`. |\n| `HOLA_RESPONSE_FAILED` | 400 | Server could not build outbound test HOLA (`/api/testhola` only) |\n\nPeer verification outcomes (`verified`, `failureReasons`) on `POST /api/identity/verify` are documented in [HOLA agent authentication](hola-agent-authentication.md).\n\n### Login (JWT) verification errors\n\n`POST /api/login` credential failures (HTTP 401 when silent login is off) use **login-lane** codes — not `HOLA_*`. Full list: [login-authentication.md — Machine-readable login errors](login-authentication.md#machine-readable-login-errors).\n\n| Code | Status | Description |\n|------|--------|-------------|\n| `LOGIN_CHALLENGE_TIMESTAMP_INVALID` | 401 | Login challenge Unix `timestamp` rejected; must align with **login challenge pair** from `GET /api/login/timestamp`. |\n| `LOGIN_BASE64URL_SIGNATURE_INVALID` | 401 | **base64url login signature** did not verify over UTF-8 **login signing payload** (`roditid` or `accountid` + canonical `timestamp_iso` from that challenge). |\n| `WEBHOOK_SIGNATURE_INVALID` | 401 | Webhook Ed25519 verification failed (outbound webhooks; not returned from `POST /api/login`). |\n\nOther chain or policy outcomes on login (`RODIT_NOT_FOUND`, `RODIT_NOT_LIVE`, …) are listed in the same login guide section.\n\n## Versioning\n\nSee **[versioning.md](versioning.md)** — HTTP API release in swagger; RODiT JSON-LD `version` only via MCP from chain; `did:rodit` has no separate version.\n\n**HTTP API release** — only [`api-docs/swagger.json`](../../api-docs/swagger.json) `info.version`. Surfaces: `GET /`, `GET /openapi.json`, MCP health/service info. Logged at boot as `apiReleaseVersion` in the configuration snapshot. Different **development** vs **main** API versions are done by committing different swagger on each branch (not via `config/development.json`). CI: `npm run validate:version`.\n\n`X-API-Version` is **not** implemented.\n\n---\n\n## Next Steps\n\n- [API Login Authentication](login-authentication.md)\n- [HOLA Protocol (Inter-Agent)](hola-agent-authentication.md)\n- [Understand token metadata](token-metadata.md)\n- [View JSON-LD integration](jsonld-metadata.md)\n- [Return to main guide](skills.md)\n- [OpenAPI spec](https://api.identyclaw.com/openapi.json)\n\nFile v1.9.6:references/collaboration-envelope.md\n\n# Channel-Agnostic Collaboration Envelope\n\n**Schema:** `identyclaw.collaboration.v1`  \n**MCP resource URI:** `doc:reference:collaboration-envelope`\n\nIdentyClaw provides **identity and trust**, not transport. Email, chat, webhooks, game private side-channels, and paste-in-message channels each need a shared envelope so agents can attach cryptographic trust (HOLA), carry a task payload, and verify inbound messages uniformly.\n\n**HOLA travels offline, peer-to-peer.** Agents exchange envelopes and HOLA lines **directly** on the channel they already use. Each peer **verifies independently** (IdentyClaw API or direct NEAR RPC — peer's choice). Do not route HOLA **exchange** through IdentyClaw HTTP API or a game server — those are separate services, not brokers for the wire path.\n\n**Related:** MCP `doc:reference:inter-agent-communication` (optional email/Himalaya patterns — **out of scope** for the ClawHub `identyclaw` skill; A2A uses the separate plugin), [`multi-tenant-collaboration.md`](multi-tenant-collaboration.md) (operator patterns), [`identity-verification-policy.md`](identity-verification-policy.md) (proof bar), `doc:reference:hola-subagent-authentication`, `doc:reference:openclaw-integration-guide`.\n\n---\n\n## Envelope shape\n\n```json\n{\n  \"schema\": \"identyclaw.collaboration.v1\",\n  \"messageId\": \"01HXABCDEFGHJKMNPQRSTVWXYZ0\",\n  \"timestamp\": \"2026-06-06T12:00:00.000Z\",\n  \"from\": { \"tokenId\": \"bkbvehbdcrgm\" },\n  \"to\": { \"tokenId\": \"lncnsfsnskzr\", \"contactUri\": \"mailto:agent@example.com\" },\n  \"hola\": \"HOLA/MUNDO/bkbvehbdcrgm/2026-06-06T12:00:00.000Z/4F9A3C7E2D1B9A4C/API.IDENTYCLAW.COM/MFRGG.../J\",\n  \"task\": {\n    \"type\": \"TASK_REQUEST\",\n    \"payload\": {\n      \"summary\": \"Run benchmark X and return JSON metrics\"\n    }\n  },\n  \"channelHints\": {\n    \"replyVia\": \"contactUri\",\n    \"subjectPrefix\": \"TASK_RESULT:\"\n  }\n}\n```\n\n| Field | Required | Notes |\n| --- | --- | --- |\n| `schema` | yes | Must be `identyclaw.collaboration.v1` |\n| `messageId` | yes | ULID or UUID — dedupe on receiver |\n| `timestamp` | yes | ISO 8601 UTC — reject stale envelopes beyond HOLA TTL |\n| `from.tokenId` | yes | Sender Passport ID (12 lowercase letters) |\n| `to.tokenId` | no | Intended recipient Passport ID |\n| `to.contactUri` | no | Routing hint from sender's view (`mailto:`, `https://`, etc.) |\n| `hola` | yes* | Full HOLA line from sender (*omit only in trusted internal channels with separate verify) |\n| `task` | yes | `{ type, payload }` — channel-independent work description |\n| `channelHints` | no | Reply routing (`subjectPrefix`, `replyVia`) |\n\n**Subagent delegation:** When `hola` uses the subagent format, also run `POST /api/isauthorizedsigner` after verify succeeds — see `doc:reference:hola-subagent-authentication`.\n\n---\n\n## Verification order (receiver)\n\n**Verify before execute** — the norm for every channel. Copy-paste verifier recipes: [`verify-hola-recipes.md`](verify-hola-recipes.md) (MCP `doc:reference:verify-hola-recipes`).\n\n1. **Parse** — valid JSON, `schema === identyclaw.collaboration.v1`, required fields present.\n2. **Freshness** — `timestamp` within acceptable window (align with HOLA nonce TTL, ~5 minutes).\n3. **Trust HOLA** — each receiving peer verifies **independently**: **IdentyClaw API** (`POST /api/identity/verify`) or **direct NEAR RPC** (e.g. `@rodit/rodit-auth-be`) — peer's choice. Proceed only when the full proof bar passes.\n4. **Identity match** — `result.peerTokenId` must equal `from.tokenId` (impersonation guard).\n5. **Subagent** — if delegation fields present in HOLA, `POST /api/isauthorizedsigner` must return `authorized: true`.\n6. **Lookup** — optional `GET /api/identity/token/{peerTokenId}/full` for `contactUri` and traits (self-declared).\n7. **Process task** — execute `task.payload` only after steps 3–5 pass.\n\n```bash\ncurl -sS -X POST https://api.identyclaw.com/api/identity/verify \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"hola\":\"<envelope.hola>\"}'\n# Optional: -H \"Authorization: Bearer $JWT\"\n```\n\nTrust **full independent validation** (either verify path) — not local checksum checks alone.\n\n---\n\n## Embedding rules by channel\n\n### Email\n\n- **Subject:** `{channelHints.subjectPrefix}{task.type}` — e.g. `TASK_REQUEST:benchmark`\n- **Body:** JSON envelope in a fenced code block, or `Content-Type: application/json` attachment named `identyclaw-envelope.json`\n- **HOLA alternative:** Include `hola` in body text per MCP `doc:reference:inter-agent-communication` (email channel) or verify over A2A with the separate plugin\n\nExample subject/body:\n\n```text\nSubject: TASK_REQUEST:benchmark\nBody:\n--- identyclaw.collaboration.v1 ---\n{ ... full JSON envelope ... }\n```\n\n### OpenClaw webhook (`/hooks/agent`)\n\n- POST body may wrap the envelope in `data.envelope` or pass the envelope as the root JSON when the event originates from a trusted bridge.\n- Map `task.type` to an isolated agent prompt; verify `hola` before tool execution — see `doc:reference:openclaw-integration-guide`.\n\n### Chat / paste block\n\n```text\n```identyclaw\n{ ... envelope JSON ... }\n```\n```\n\nReceivers extract the block, then run the verification order above.\n\n---\n\n## Example flows\n\n### Email outbound (agent A → agent B)\n\n1. A fetches nonce, signs HOLA to B's recipient slot.\n2. A builds envelope with `task.type: \"TASK_REQUEST\"`.\n3. A sends via Himalaya/SMTP to B's `contactUri` (`mailto:...`).\n4. B parses envelope → verify HOLA → processes task → replies with `TASK_RESULT:` envelope.\n\n### Hermes / IronClaw / NanoClaw / generic HTTP agent\n\n1. Agent receives envelope JSON on Telegram, Discord, email, HTTP, or paste.\n2. `POST /api/identity/verify` with `envelope.hola` (public — no JWT).\n3. On `verified: true`, match `peerTokenId` to `from.tokenId`.\n4. Execute `task.payload` only after steps 2–3 succeed.\n5. Reply with a new envelope + fresh HOLA on the same channel.\n\nLogin for outbound HOLA: host script [`scripts/identyclaw-login.mjs`](../../scripts/identyclaw-login.mjs) or `@rodit/hola-client`. See [`agent-frameworks.md`](agent-frameworks.md#what-this-api--repo-provides-all-runtimes).\n\n### Non-OpenClaw webhook ingress\n\nSame crypto as the OpenClaw webhooks plugin; different host:\n\n1. Set Passport `webhook_url` to your agent HTTPS **base** (no required `/hooks/agent` in metadata).\n2. Trusted host process listens on `/webhook`, `/hooks/agent`, or your path.\n3. Verify Ed25519 with `@rodit/rodit-auth-be` — reject invalid signatures.\n4. If payload includes `hola` or a collaboration envelope, run verify-before-execute (order above) before tools.\n\n### OpenClaw inbound webhook\n\n1. IdentyClaw or a bridge POSTs to `/hooks/agent` with envelope in body.\n2. OpenClaw agent verifies webhook signature (IdentyClaw-origin events) separately from HOLA trust.\n3. Agent calls `identyclaw_verify_hola` / `/api/identity/verify` on `envelope.hola`.\n4. On success, spawn task from `envelope.task.payload`.\n\n---\n\n## Replay and stale messages\n\n- HOLA nonces are single-use (~5 minute window) — stale `timestamp` or replayed nonce → `verified: false`.\n- Receivers should dedupe on `messageId`.\n- Reject envelopes whose `timestamp` is far in the future or past relative to receiver clock.\n\n---\n\n## Non-goals\n\n- IdentyClaw does **not** deliver messages — transport remains Himalaya, webhooks, human paste, etc.\n- This spec does **not** change the HOLA wire format — it wraps existing lines.\n- Programmatic builders live in `@rodit/hola-client` (`buildCollaborationEnvelope`, `parseCollaborationEnvelope`, `formatSessionsSendMessage`). Reference skill: `identyclaw-a2a-trust-skill/` (covers `sessions_send` and A2A message bodies; A2A wire auth is `@identyclaw/openclaw-a2a-plugin` P2P JWT only).\n\n---\n\n## OpenClaw plugin tools\n\n| Tool | Use |\n| --- | --- |\n| `identyclaw_verify_hola` | Step 3 — trust decision |\n| `identyclaw_get_agent_identity` | Step 6 — `contactUri` and DN |\n| `identyclaw_check_subagent_signer` | Step 5 — delegation |\n\nInstall: `openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin`\n\nFile v1.9.6:references/did-rodit-method.md\n\n# The `did:rodit` Method\n\n**Status:** Draft for registration in the [W3C DID Method Registry](https://www.w3.org/TR/did-extensions-methods/). HTTP convenience resolvers on IdentyClaw APIs remain labeled experimental in OpenAPI.  \n**Canonical URL:** `https://api.identyclaw.com/.well-known/did-method-rodit`  \n**Normative references:** [W3C DID Core 1.1](https://www.w3.org/TR/did-1.1/), [DID Resolution](https://www.w3.org/TR/did-resolution/), [did:web Method Specification](https://w3c-ccg.github.io/did-method-web/), [RFC 5234](https://www.rfc-editor.org/rfc/rfc5234), [RFC 3552](https://www.rfc-editor.org/rfc/rfc3552), [RFC 6973](https://www.rfc-editor.org/rfc/rfc6973)\n\nThis document is the DID method specification for **`did:rodit`**. It identifies Rich Online Digital Identity Tokens (RODiT / IdentyClaw Passports): transferable, universally unique agent identities recorded as non-fungible tokens on a NEAR Protocol smart contract.\n\nA `did:rodit` identifier is the portable Passport DID. It does not encode an API hostname or a contract account. Resolvers pin a verifiable data registry (NEAR mainnet + a trusted RODiT contract) and construct the DID document from current on-chain state.\n\n---\n\n## 1. Method name\n\n| Property | Value |\n|----------|--------|\n| **Method name** | `rodit` |\n| **DID scheme** | `did:rodit:<passport-id>` |\n| **Verifiable data registry** | NEAR Protocol (mainnet) RODiT contract |\n\nThe method name uses only lowercase ASCII letters (`r`, `o`, `d`, `i`, `t`) and matches the DID Core `method-name` production (`1*method-char` where `method-char = %x61-7A / DIGIT`).\n\nThis specification defines **exactly one** method-specific DID scheme, identified by the method name `rodit`.\n\n**Do not use** NEAR contract account IDs (for example `rodit.near` or `genaaaa-identyclaw-com.near`) in the DID string. Contract deployment is resolver configuration and on-chain metadata (`serviceprovider_id`), not part of the identifier.\n\n---\n\n## 2. Method-specific identifier\n\n### 2.1 ABNF (normative)\n\nThe following ABNF uses [RFC 5234](https://www.rfc-editor.org/rfc/rfc5234). It is a restriction of DID Core `method-specific-id`:\n\n```\nrodit-did           = \"did:\" rodit-method-name \":\" rodit-specific-id\nrodit-method-name   = \"rodit\"\nrodit-specific-id   = 12( lowercase-alpha )\nlowercase-alpha     = %x61-7A\n```\n\nExamples: `did:rodit:bkbvehbdcrgm`, `did:rodit:lhsrldbjsnlh`.\n\nThis method does **not** use colons inside `method-specific-id`. DID path, query, and fragment components follow DID Core / RFC 3986; this method does not define a more restrictive path or query syntax. The fragment `controller` is reserved for the primary verification method (see §5).\n\n### 2.2 Generation\n\nThe method-specific identifier **is** the Passport `token_id` assigned when the RODiT is minted on the pinned contract.\n\n1. At Create (§4.1), the minter supplies (or the issuance flow assigns) a 12-character `token_id`.\n2. Characters 1–11 encode categorical facial-trait selections used as a human-recognisable agent face. Character 12 is a checksum over those selections. Encoding tables live in the Passport metadata reference; they are **not** required to parse or resolve a DID.\n3. The contract rejects a mint if that `token_id` already exists on that contract.\n4. The DID is then `did:rodit:` concatenated with that `token_id`. The DID document is **not** stored as a separate object; it is derived at Read time from the token record and the current owner’s NEAR keys.\n\nAny 12-letter string that exists as `token_id` on the pinned contract is a valid method-specific identifier. Strings that do not match §2.1 are invalid DIDs (`INVALID_DID`). Strings that match §2.1 but have no token record are valid DIDs that do not (currently) resolve (`DID_NOT_FOUND`).\n\n### 2.3 Sensitivity, normalization, and uniqueness\n\n| Rule | Requirement |\n|------|-------------|\n| **Length** | Exactly 12 characters |\n| **Charset** | Lowercase ASCII letters `a`–`z` only |\n| **Case** | Identifiers are **case-sensitive** as written in the DID string. Resolvers MUST reject uppercase letters as invalid syntax. Passport IDs are stored and compared in lowercase on chain. |\n| **Normalization** | No Unicode normalization. Implementations MAY trim surrounding whitespace on input, then MUST apply the ABNF. |\n| **Uniqueness** | `token_id` is unique **within the pinned RODiT contract**. Minting rejects duplicates. The identifier is designed to be globally unique for a given trusted contract; it does not encode a local namespace, tenant, or API host. |\n| **Global uniqueness of DIDs** | `did:rodit:<passport-id>` is globally unique as a URI. Two resolvers that pin **different** contracts could theoretically see the same 12-letter id refer to different tokens (an operational failure, not an expected namespace). Resolvers MUST pin the contract they trust. |\n\n---\n\n## 3. Verifiable data registry\n\n`did:rodit` is anchored on **NEAR Protocol mainnet**. The DID document is derived from a RODiT smart-contract account that stores Passport NFTs.\n\n### 3.1 Canonical production registry\n\n| Setting | Canonical production value |\n|---------|----------------------------|\n| **Network** | NEAR mainnet |\n| **Contract account** | `genaaaa-identyclaw-com.near` |\n| **View (Read)** | `rodit_token` |\n| **Create** | `rodit_mint` |\n| **Update (controller)** | `rodit_transfer` |\n| **Destroy** | `rodit_burn` |\n| **List (optional)** | `rodit_tokens` |\n\nIndependent resolvers MUST pin a contract account. For public IdentyClaw Passports, pin `genaaaa-identyclaw-com.near` unless an operator has published a different trusted registry.\n\nDevelopment IdentyClaw stacks may pin a different mainnet account (pattern `YYYYYvN-identyclaw-com.near`). The DID string does not encode which contract is used.\n\n### 3.2 IdentyClaw HTTP resolver configuration\n\nIdentyClaw API instances read:\n\n| Setting | Source | Purpose |\n|---------|--------|---------|\n| **`NEAR_CONTRACT_ID`** | Host config or env | RODiT contract account to pin |\n| **`NEAR_RPC_URL`** | Host config or env | NEAR RPC endpoint for on-chain reads |\n\nThat HTTP resolver is a **convenience** implementation of Read. It is not the verifiable data registry.\n\n---\n\n## 4. Method operations\n\nAuthorization for all mutating operations is performed **on chain** by the RODiT contract using the NEAR predecessor account and, for mint, a fee attestation from the contract’s authorized-signer set. The DID document is not consulted to authorize Create, Update, or Destroy. Read is unauthenticated against the ledger.\n\n### 4.1 Create\n\nA DID controller creates a `did:rodit` DID by minting a Passport NFT whose `token_id` becomes the method-specific identifier.\n\n**Authorization.** The mint transaction must (1) be signed by a NEAR account that will own the token, (2) include a fee attestation accepted by the contract’s authorized-signer set, and (3) attach the attested deposit. The contract MUST reject a `token_id` that already exists.\n\n**Procedure (normative outcome).**\n\n1. Create or reuse a NEAR account whose full-access key is Ed25519. Implicit accounts (64-character lowercase hex of the public key) are typical.\n2. Obtain issuance (purchase / sign-portal attestation) so the contract will accept `rodit_mint`.\n3. Submit `rodit_mint` on the pinned contract with the chosen `token_id`, owner account, and Passport metadata (validity window, DN, policy fields).\n4. On success the contract stores `{ token_id, owner_id, metadata }` and emits a mint event.\n5. The DID `did:rodit:<token_id>` now exists. The associated DID document is the document that Read would return for that DID at that block.\n\nThe DID document is **generative**: it is not written to the ledger as JSON-LD. Create succeeds when the token record exists.\n\nIdentyClaw’s hosted issuance UI is `https://purchase.identyclaw.com`. Other issuers MAY call `rodit_mint` if they can satisfy the contract’s attestation and deposit rules.\n\n### 4.2 Read (Resolve)\n\nA DID resolver uses the DID to construct a DID document from current chain state.\n\n**Inputs.** A `did:rodit` DID; a pinned contract account; a NEAR RPC endpoint; optional resolution options (this method does not define custom DID parameters).\n\n**Algorithm (normative).**\n\n1. Confirm the DID matches §2.1. Otherwise fail with `invalidDid`.\n2. Let `passport-id` be the `rodit-specific-id`.\n3. Call the pinned contract view method `rodit_token` with JSON arguments `{ \"token_id\": \"<passport-id>\" }` at finality `final` (or the caller’s chosen NEAR finality).\n4. If the result is missing or has no `token_id`, fail with `notFound`.\n5. Let `owner_id` be the token’s `owner_id`.\n6. Fetch an Ed25519 full-access public key for `owner_id` from NEAR (account access-key query). If none is available, fail resolution (the DID exists but the verification method cannot be built).\n7. Encode that 32-byte public key as Base58 (Bitcoin alphabet) for `publicKeyBase58`.\n8. Return the DID document in §5.1. `id` MUST be `did:rodit:<passport-id>`.\n\n**Authenticity of the response.** The DID document is not a separately signed object. Verifiers authenticate Read by (a) pinning the contract account, (b) using a NEAR RPC they trust (or multiple RPCs), and (c) relying on NEAR consensus / the chosen finality. A MITM on an untrusted RPC can lie about token state. Independent resolvers SHOULD prefer well-known public RPCs or their own node.\n\n**IdentyClaw HTTP convenience resolver** (non-normative for the method; documents current API behavior):\n\nLet `{base}` be an IdentyClaw API origin (for example `https://api.identyclaw.com`).\n\n| Operation | HTTP | URL | Auth |\n|-----------|------|-----|------|\n| Resolve by passport id | `GET` | `{base}/.well-known/did/rodit/{passport-id}` | JWT Bearer |\n| Resolve by DID string | `GET` | `{base}/.well-known/did/resolve?did={url-encoded-did}` | JWT Bearer |\n| Resolve as `did:web` alias | `GET` | `{base}/.well-known/did/web/token/{passport-id}` | JWT Bearer |\n| Same, `did.json` suffix | `GET` | `{base}/.well-known/did/web/token/{passport-id}/did.json` | JWT Bearer |\n| MCP resource | MCP `get_resource` | `did:resolve:{passport-id}` | MCP (public docs transport) |\n\nUnauthenticated callers of those HTTP paths receive an authentication error. **JWT on the HTTP resolver does not replace pinning the contract.** Peers MAY implement Read solely via NEAR RPC and skip the HTTP API.\n\nMCP:\n\n| MCP resource URI | Description |\n|------------------|-------------|\n| `did:resolve:{passport-id}` | DID document JSON (12-letter id) |\n| `doc:reference:did-rodit-method` | This specification (Markdown, JSON wrapper) |\n\n### 4.3 Update\n\nAn **update** to a `did:rodit` DID document is a change to the current controller key material: the on-chain `owner_id` and therefore the `verificationMethod` public key constructed at Read.\n\n**How the controller updates.** The current token owner calls `rodit_transfer` on the pinned contract:\n\n```\nrodit_transfer(receiver_id: AccountId, token_id: String, memo: Option<String>)\n```\n\n**Authorization.** The NEAR predecessor MUST be the current `owner_id`. The attached deposit MUST be exactly 0.01 NEAR. `receiver_id` MUST differ from the sender. On success the contract updates `owner_id` and emits a `rodit_transfer` event.\n\nThe 12-letter DID does **not** change. Subsequent Read uses the new owner’s keys. Transfer is also the key-rotation mechanism; observers cannot distinguish rotation from change of custody.\n\n**What cannot be updated.** Passport metadata (validity window, DN, policy fields, `token_id`) is **immutable** after mint. There is no `update_metadata` method. Extending `not_after` requires minting a **new** Passport (a new DID).\n\n### 4.4 Deactivate\n\n**Holder-driven deactivation is not possible.** The DID controller (current token owner) cannot burn or tombstone the identifier through a public controller operation.\n\n**Privileged destroy.** The contract implements `rodit_burn`. That method is authorized by the contract’s own access-control (registry owner / predecessor rules), not by DID document `authentication`. After a successful burn, `rodit_token` no longer returns the record and Read MUST fail with `notFound`.\n\n**Expiry is not deactivation.** Metadata `not_after` (unless the unbounded sentinel `1970-01-01`) is a validity window for **authentication and API use**. An expired token MAY still resolve to a DID document. Verifiers that use Passports as credentials MUST treat an expired `not_after` as inactive for proofs (HOLA, login) even if Read succeeds. `not_before` / `not_after` are not rewritten in place.\n\nThere is no holder revocation list and no graduated DID document `deactivated` flag in the current contract. Effective invalidation for relying parties is: burn (token gone), expiry (token present but inactive for proofs), or local policy.\n\n---\n\n## 5. DID document\n\n### 5.1 `did:rodit` primary form\n\n| Field | Value |\n|--------|--------|\n| `id` | `did:rodit:<passport-id>` |\n| `alsoKnownAs` | `did:web:<host>:token:<passport-id>` when an HTTP host is known (`:` in host percent-encoded as `%3A`) |\n| `controller` | NEAR account id of the current token owner (a NEAR account string, **not** a DID). This is method-specific. |\n| `verificationMethod[]` | One entry: `id` = `{did}#controller`, `type` = `Ed25519VerificationKey2020`, `controller` = `{did}`, `publicKeyBase58` = owner Ed25519 key |\n| `authentication` / `assertionMethod` | `[ \"{did}#controller\" ]` |\n| `service[]` | `RoditTokenMetadata` (embedded Passport metadata) and `MCPDiscoveryService` (HTTP resolver’s `/api/mcp/resources` when a base URL is known) |\n\n`@context` includes `https://www.w3.org/ns/did/v1` and the IdentyClaw RODiT vocabulary (`https://identyclaw.com/ns/rodit#`).\n\nThe fragment `controller` on the verification method is the only fragment this method defines. Other fragments MAY appear as `service` ids (`#metadata`, `#mcp-discovery`).\n\n### 5.2 Example (illustrative)\n\n```json\n{\n  \"@context\": [\n    \"https://www.w3.org/ns/did/v1\",\n    {\n      \"rodit\": \"https://identyclaw.com/ns/rodit#\",\n      \"RoditTokenMetadata\": \"https://identyclaw.com/ns/services#RoditTokenMetadata\",\n      \"MCPDiscoveryService\": \"https://identyclaw.com/ns/services#MCPDiscoveryService\"\n    }\n  ],\n  \"id\": \"did:rodit:bkbvehbdcrgm\",\n  \"alsoKnownAs\": [\n    \"did:web:api.identyclaw.com:token:bkbvehbdcrgm\"\n  ],\n  \"controller\": \"abc123def4567890123456789012345678901234567890123456789012345678\",\n  \"verificationMethod\": [\n    {\n      \"id\": \"did:rodit:bkbvehbdcrgm#controller\",\n      \"type\": \"Ed25519VerificationKey2020\",\n      \"controller\": \"did:rodit:bkbvehbdcrgm\",\n      \"publicKeyBase58\": \"...\"\n    }\n  ],\n  \"authentication\": [\"did:rodit:bkbvehbdcrgm#controller\"],\n  \"assertionMethod\": [\"did:rodit:bkbvehbdcrgm#controller\"],\n  \"service\": [\n    {\n      \"id\": \"did:rodit:bkbvehbdcrgm#metadata\",\n      \"type\": \"RoditTokenMetadata\",\n      \"serviceEndpoint\": { \"type\": \"RODiTMetadataDocument\", \"tokenId\": \"bkbvehbdcrgm\", \"metadata\": {} }\n    },\n    {\n      \"id\": \"did:rodit:bkbvehbdcrgm#mcp-discovery\",\n      \"type\": \"MCPDiscoveryService\",\n      \"serviceEndpoint\": \"https://api.identyclaw.com/api/mcp/resources\"\n    }\n  ]\n}\n```\n\n`RoditTokenMetadata.serviceEndpoint` MAY embed on-chain metadata (DN, webhook URL, validity window, contract account). Treat embedded metadata as **public ledger data**, not a confidential claims channel.\n\n---\n\n## 6. Relationship to `did:web`\n\n| Aspect | `did:rodit` | `did:web` (alias) |\n|--------|-------------|-------------------|\n| **Purpose** | Stable, host-agnostic Passport identifier | HTTPS-oriented identifier tied to a serving API host |\n| **Form** | `did:rodit:<passport-id>` | `did:web:<host>:token:<passport-id>` |\n| **Primary in IdentyClaw HTTP** | Default for `/.well-known/did/rodit/...` | Primary when resolving via `/.well-known/did/web/token/...` |\n| **Document** | Same logical document; `id` and `alsoKnownAs` swap roles | Same |\n| **Generic did:web resolvers** | N/A | May work only if the host exposes unauthenticated well-known DID URLs; IdentyClaw HTTP currently requires JWT on those paths |\n\nIntegrators SHOULD treat **`did:rodit`** as the portable Passport DID and **`did:web`** as a deployment-scoped alias for the same passport on a given API hostname.\n\n---\n\n## 7. Supported DID methods on IdentyClaw HTTP resolvers\n\n| Method | Supported | Notes |\n|--------|-----------|--------|\n| `rodit` | Yes | This specification |\n| `web` | Yes | Path must include `:token:<passport-id>` after host segments |\n| `wba`, others | No | Rejected with `INVALID_DID` |\n\nLegacy documentation that referred to `did:wba:rodit.near:…` is withdrawn. On-chain JSON-LD views MAY still expose `did_wba_jsonld`; HTTP DID resolution uses `did:rodit` / `did:web` only.\n\n---\n\n## 8. Stability\n\n- This specification is the registration document for method name `rodit`. Breaking changes to syntax or CRUD semantics require an update to this document and to any W3C registry entry that points here.\n- OpenAPI `/.well-known/did/*` **resolution** operations on IdentyClaw HTTP APIs are labeled **EXPERIMENTAL** and may change when `api-docs/swagger.json` `info.version` bumps. That label applies to the paid HTTP convenience API, not to the on-chain identifier syntax.\n- The method has no separate on-chain version field. Passport JSON-LD `version` on the contract is independent (fetch via MCP `jsonld:contract-metadata`).\n\n---\n\n## 9. Security considerations\n\nThis section follows [RFC 3552](https://www.rfc-editor.org/rfc/rfc3552) for the operations in §4. `did:rodit` inherits NEAR’s consensus and account-key model. Residual risk remains whenever a resolver uses a third-party RPC or an unpinned contract.\n\n### 9.1 Unique assignment\n\nDIDs are uniquely assigned by contract-enforced uniqueness of `token_id` on the pinned registry. Duplicate mint of the same 12-letter id on that contract fails. Uniqueness across **unrelated** contracts is not a ledger invariant; trust is the resolver’s pin (see §2.3). Economic mint cost raises the price of mass-producing look-alike Passports but does not bind display names.\n\n### 9.2 Integrity protection and update authentication\n\nCreate, Update, and Destroy are NEAR transactions: Ed25519 signatures over NEAR transaction payloads, replay-protected by NEAR nonces, and ordered by chain consensus. Read is a view call; integrity is the RPC’s response authenticity plus consensus at the requested finality. The constructed DID document is **not** an additional signed envelope. Implementations MUST NOT treat HTTP JSON from an IdentyClaw API as stronger than the chain view unless they also authenticate that API.\n\nKey material that MUST remain secret: NEAR account private keys used as `authentication` / `assertionMethod`, issuance/attestation keys, and JWT session secrets for the convenience API. Public keys, `token_id`, `owner_id`, and Passport metadata are public ledger data.\n\n### 9.3 Attacks (RFC 3552)\n\n| Attack | Method-specific consideration |\n|--------|-------------------------------|\n| **Eavesdropping** | Token records and DID documents contain no encryption. Anyone with RPC access can Read. Confidential attributes MUST NOT be placed in on-chain DN if confidentiality is required. TLS protects IdentyClaw HTTP resolvers in transit; it does not hide ledger state. |\n| **Replay** | Ledger operations use NEAR transaction nonces. HTTP JWT resolution sessions are replayable until JWT expiry. HOLA proofs (outside this method) use fresh nonces; DID Read itself has no proof-of-possession. |\n| **Message insertion** | A malicious RPC can fabricate `rodit_token` results. Mitigate by pinning contract id, using trusted RPC (or several), and optionally checking block hash/height. Inserting a fake mint on a **different** contract does not affect resolvers that pin the canonical account. |\n| **Deletion** | A malicious RPC can omit a token (false `notFound`). Burn by the registry owner is real deletion. Holders cannot delete. |\n| **Modification** | Unauthorized `rodit_transfer` requires the current owner’s key. Metadata cannot be modified after mint. A lying RPC can modify the **reported** document; compare independent RPCs for high assurance. |\n| **Denial of service** | NEAR RPC, mint deposits, and HTTP rate limits are DoS surfaces. View calls are cheaper than mints; public list (`rodit_tokens`) can be paginated. Thin-client resolvers depend on RPC availability (see §9.6). |\n| **Amplification** | `rodit_token` responses include metadata and can be larger than the request. HTTP DID documents embed metadata. Resolvers SHOULD cap response size and rate-limit public interfaces. |\n| **Man-in-the-middle** | TLS MITM on HTTP resolvers can alter DID JSON. RPC MITM can alter chain views. Pinning contract + TLS + trusted RPC are the mitigations. DID Read does not by itself authenticate the **presenter**. |\n\n### 9.4 Authentication characteristics\n\nResolution **does not** prove live possession of the controller key. A copied DID document or a screenshot of a `token_id` is not a login. Proof-of-possession for IdentyClaw is HOLA (peer lane) or JWT login (session lane), both of which sign with the current owner (or a delegated subagent key) over fresh challenge data. Those protocols are specified elsewhere; this method only supplies the current verification method.\n\nIdentyClaw HTTP `/.well-known/did/*` requires a JWT because resolution is a metered API feature, not because DID Core requires authentication for Read.\n\n### 9.5 Endpoint authentication and topology\n\nNEAR is a public DLT. Light clients and HTTPS RPC gateways (including public `rpc.mainnet.near.org` and third-party RPCs) are common. Security assumptions:\n\n- A **full node** verifying NEAR state proofs has the strongest Read authenticity.\n- A **trusted RPC** is equivalent to trusting that operator for token existence, owner, and keys.\n- IdentyClaw’s HTTP resolver is an additional trusted party for callers who do not query NEAR themselves.\n\nService endpoints in the DID document (`RoditTokenMetadata`, `MCPDiscoveryService`) are **not** authenticated by this method beyond the integrity of Read. Webhook URLs and ContactURI values are self-declared and unsigned relative to the issuance signature over policy fields.\n\n### 9.6 Residual risks\n\n- Compromise of the owner’s NEAR private key allows Update (transfer) and impersonation in proof protocols.\n- Compromise of registry burn authority allows Destroy.\n- Incorrect resolver implementation (wrong contract pin, accepting uppercase ids, skipping finality) yields false documents.\n- Cipher/algorithm: Ed25519 as used by NEAR implicit accounts. A break of Ed25519 or NEAR account-key semantics would break this method.\n- Related protocols (HOLA, JWT login, DNS TXT registry attestation in some SDKs) have their own residual risks; a valid DID document does not imply those checks passed.\n- Impersonation via look-alike DN: compare the attested `token_id` with out-of-band publication on channels the subject controls.\n\nSignatures on DID documents: this method does **not** require a `proof` on the DID document. Authenticity is ledger state plus RPC trust.\n\n---\n\n## 10. Privacy considerations\n\nPassport records are written to a public blockchain. This method is **not** suitable for identifiers whose associated attributes must remain confidential. The following maps [RFC 6973](https://www.rfc-editor.org/rfc/rfc6973) §5 to `did:rodit`.\n\n### 10.1 Surveillance\n\nAnyone who can query NEAR can enumerate or look up Passports (`rodit_token`, `rodit_tokens`) and observe owner accounts, transfer history, and metadata. There is no access-control on ledger Read. HTTP convenience resolvers currently require JWT, which reduces casual scraping of **that API** but does not prevent chain surveillance. Resolvers and API operators can log resolution requests (IP, `token_id`, JWT subject).\n\n### 10.2 Stored data compromise\n\nOn-chain data cannot be deleted by the holder (see §4.4). Operator logs (HTTP resolvers, RPC providers, purchase portal) MAY store IP addresses, account ids, and request metadata. Compromise of those stores leaks **who resolved which DID**, not holder private keys (unless logs were misconfigured). Private keys MUST be stored off-chain by the holder.\n\n### 10.3 Unsolicited traffic\n\n`ContactURI`, `webhook_url`, and similar metadata can be used to message the subject. They are self-declared routing hints, not proof of control. Publishing a DID and metadata on a public ledger enables unsolicited contact. Subjects SHOULD use monitored ContactURI values and treat inbound messages as untrusted until a proof-of-possession check succeeds.\n\n### 10.4 Misattribution\n\nDN fields (names, Creature, ContactURI) are **self-declared**. A different actor can mint another Passport with similar display strings. Attribution of a human or brand to a DID MUST use out-of-band binding of the 12-letter `token_id`, not DN string matching. The facial encoding is a categorical agent appearance, not a biometric of a person.\n\n### 10.5 Correlation\n\nThe same `did:rodit:<id>` is globally correlatable across APIs, HOLA, A2A cards, and the ledger. Transfer to a new NEAR account rotates keys but **not** the DID, so correlation to the persistent identifier remains. Using distinct Passports for distinct contexts is the only method-level anti-correlation control.\n\n### 10.6 Identification\n\nThe method-specific id is a stable unique identifier. Combined with public DN, avatar URLs, and owner account history, it can identify a person or organisation who chose to put those fields on chain. Facial trait letters may be socially identifying if they match a published portrait.\n\n### 10.7 Secondary use\n\nLedger history (mint time, transfers, metadata) can be reused by third parties for analytics, scoring, or unsolicited profiling without the subject’s further consent. This specification cannot prevent secondary use of public chain data.\n\n### 10.8 Disclosure\n\nCreate discloses `token_id`, owner account, and metadata to the world. Read discloses the current verification key. There is no selective-disclosure mode in the DID document. Do not mint tax identifiers, precise birth data, or other sensitive DN attributes if disclosure is unacceptable; those fields are optional in Passport DN.\n\n### 10.9 Exclusion\n\nParticipation requires a NEAR account, mint deposit / fee, and the ability to complete issuance attestation. That excludes people who cannot obtain NEAR or pay the fee. Burn and seizure (privileged) can exclude a subject from the registry without a holder appeal path in this method. Unbounded (`1970-01-01`) validity is an issuer policy choice, not a right.\n\n---\n\n## 11. Intellectual property\n\nCopyright © Discernible Inc. Implementers MAY use this specification to implement `did:rodit` identifiers, resolvers, and related software. IdentyClaw and RODiT are used as product names; no trademark license is granted beyond nominative use in implementations and registry entries.\n\nRegistration contact: Discernible Inc. / IdentyClaw — `support@identyclaw.com` — `https://identyclaw.com`.\n\n---\n\n## 12. Related documentation\n\nIn-repo (also via MCP `doc:reference:*` and, for this spec, `GET /.well-known/did-method-rodit`):\n\n- [did-method-registry-submission.md](did-method-registry-submission.md) — W3C DID Extensions PR checklist\n- [versioning.md](versioning.md) — HTTP API release vs on-chain JSON-LD\n- [api-reference.md](api-reference.md#did-resolution) — HTTP endpoints\n- [jsonld-metadata.md](jsonld-metadata.md) — Semantic mappings\n- [token-metadata.md](token-metadata.md) — Passport fields and facial encoding\n- [key-rotation.md](key-rotation.md) — `rodit_transfer`\n- [enrollment.md](enrollment.md) — issuance / mint\n- [finding-agents.md](finding-agents.md) — impersonation guard\n\nFile v1.9.6:references/enrollment.md\n\n# Enrollment & Setup Guide\n\nComplete guide to setting up your IdentyClaw Passport for API access.\n\nThis guide is for both humans and automation agents. **OpenClaw Gateway operators** create NEAR accounts with the [openclaw-identyclaw-plugin](https://github.com/discernible-io/openclaw-identyclaw-plugin) (v1.5.0+ CLI or optional agent tool). **Hermes, IronClaw, NanoClaw, Cursor, and custom SDK clients** use `gennearaccount` (or equivalent host-side account generation) plus client-side API login. The purchase portal step is the human-operated checkout step in all paths.\n\n**Runtime routing:** see [agent-frameworks.md](agent-frameworks.md) (MCP `doc:reference:agent-frameworks`) for per-framework install links and capability matrix.\n\n## Table of Contents\n\n- [Choose your path](#choose-your-path)\n- [OpenClaw: Plugin + Skill Route](#openclaw-plugin--skill-route)\n- [Manual enrollment (all other agents)](#manual-enrollment-all-other-agents)\n- [Prerequisites](#prerequisites)\n- [Step 1: Create NEAR Account](#step-1-create-near-account)\n- [Step 2: Purchase IdentyClaw Passport](#step-2-purchase-identityclaw-passport)\n- [Step 3: Authenticate with Your NEAR Account](#step-3-authenticate-with-your-near-account)\n- [Troubleshooting](#troubleshooting)\n\n## Choose your path\n\n| Audience | Route |\n|----------|-------|\n| **OpenClaw Gateway operators** | [OpenClaw plugin + skill route](#openclaw-plugin--skill-route) — plugin generates NEAR credentials (no `gennearaccount` binary), handles JWT login and API tools after Passport purchase |\n| **Hermes Agent** | [hermes-integration-guide.md](hermes-integration-guide.md) — copy `hermes-identyclaw-skill/` to `~/.hermes/skills/` + manual enrollment below |\n| **IronClaw** | [ironclaw-integration-guide.md](ironclaw-integration-guide.md) — MCP docs + `gennearaccount` + host sidecar for login/HOLA |\n| **NanoClaw** | [nanoclaw-integration-guide.md](nanoclaw-integration-guide.md) — bind-mounted secrets + MCP/curl in container |\n| **Cursor / Claude Desktop / custom SDK / shell** | [Manual enrollment](#manual-enrollment-all-other-agents) — `gennearaccount`, curl login, MCP `doc:skills` |\n\nBoth paths share the same on-chain prerequisites: a NEAR implicit account and a minted IdentyClaw Passport. **Account creation** and **post-purchase API integration** differ by path (OpenClaw plugin vs `gennearaccount` + client-side HTTP).\n\n## OpenClaw: Plugin + Skill Route\n\n**For OpenClaw users only.** Other AI agents must follow [manual enrollment](#manual-enrollment-all-other-agents) below.\n\nThe OpenClaw route uses the **openclaw-identyclaw-plugin** (v1.5.0+) for NEAR implicit account generation and post-purchase API integration, plus a **ClawHub skill** for workflow guidance. Passport purchase remains a human checkout step.\n\n### What still requires manual steps\n\n1. **Fund the NEAR account** — transfer NEAR for checkout and transaction fees\n2. **Purchase Passport** — human checkout at https://purchase.identyclaw.com (see [Step 2](#step-2-purchase-identityclaw-passport))\n\nThere is no IdentyClaw MCP tool or plugin that replaces the purchase portal for minting. Non-OpenClaw agents must still use `gennearaccount` for account creation (see [Manual enrollment](#manual-enrollment-all-other-agents)).\n\n### What the plugin + skill replace\n\n- **`gennearaccount` on OpenClaw** — plugin operator CLI or optional `identyclaw_generate_near_account` tool writes gennearaccount-compatible JSON to `secrets/near-credentials/` (private key never returned to chat)\n- Hand-rolled `GET /api/login/timestamp` → sign → `POST /api/login` (plugin caches JWT, applies `New-Token` headers, re-logins before expiry)\n- Manual curl for identity, HOLA verify/create, agent discovery, and MCP doc fetch (plugin tools)\n- Scattered protocol docs during daily operation (skill auto-triggers on identity/HOLA/DID prompts; `identyclaw_list_resources` / `doc:discovery` for deep references)\n\n### 1. Install skill and plugin\n\n```bash\nopenclaw skills install clawhub:identyclaw\nopenclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\n```\n\n| Artifact | ClawHub | Role |\n|----------|---------|------|\n| Skill | [identyclaw/identyclaw](https://clawhub.ai/identyclaw/identyclaw) | When to use IdentyClaw, HOLA verify/create patterns, discovery guardrails |\n| Plugin | [@identyclaw/openclaw-identyclaw-plugin](https://clawhub.ai/plugins/@identyclaw/openclaw-identyclaw-plugin) | NEAR account generation, JWT login, HOLA, identity, discovery (`identyclaw_generate_near_account`, `identyclaw_get_my_identity`, …) |\n\nAfter `npm run prepare:publish` in a local checkout, install the plugin from path instead: `openclaw plugins install /path/to/openclaw-identyclaw-plugin`.\n\n### 2. Create NEAR account (OpenClaw — no `gennearaccount`)\n\nStore credentials on bind-mounted OpenClaw state ([NEAR Credentials Storage](#near-credentials-storage-required)). Output directory must end with `secrets/near-credentials` (recommended) or appear in plugin `nearCredentialsOutputDirs`.\n\n**Option A — Operator CLI (recommended)**\n\nFrom a plugin checkout on the host (or anywhere Node ≥ 22.19 is available):\n\n```bash\nnpm run generate-near-account -- /path/to/secrets/near-credentials\n# default: ./secrets/near-credentials\n# env: IDENTYCLAW_NEAR_CREDENTIALS_DIR\n```\n\nTypical OpenClaw bind-mount layout (host path; create parent dirs first):\n\n```bash\nmkdir -p ~/.openclaw-agent-a/secrets/near-credentials\nchmod 700 ~/.openclaw-agent-a/secrets/near-credentials\nnpm run generate-near-account -- ~/.openclaw-agent-a/secrets/near-credentials\n```\n\nInside the container the same directory is usually `/home/node/.openclaw/secrets/near-credentials`. The CLI prints `implicit_account_id` on stdout and writes `<implicit_account_id>.json` with mode `0600` (directory `0700`). **Private keys never appear in CLI stdout.**\n\n**Option B — Agent tool (optional, advanced)**\n\nAllowlist `identyclaw_generate_near_account` and set a default output directory:\n\n```json5\n{\n  plugins: {\n    entries: {\n      \"identyclaw-tools\": {\n        config: {\n          generateNearAccountDefaultDir: \"/home/node/.openclaw/secrets/near-credentials\",\n          nearCredentialsOutputDirs: []\n        }\n      }\n    }\n  },\n  tools: {\n    allow: [\"identyclaw_generate_near_account\"]\n  }\n}\n```\n\nThe tool returns `implicit_account_id`, `public_key`, and `filePath` only — not `private_key`.\n\nFund the new account with NEAR before purchasing a Passport.\n\n### 3. Purchase Passport\n\nComplete human checkout at https://purchase.identyclaw.com using the `implicit_account_id` from step 2. See [Step 2: Purchase IdentyClaw Passport](#step-2-purchase-identityclaw-passport) for form fields and pricing.\n\n### 4. Configure Passport credentials on the Gateway\n\nAfter purchase, point the plugin at the credentials JSON. **Never paste keys into chat** — configure them in OpenClaw config, `.env`, or identyclaw-agents bootstrap only.\n\n**Bootstrap sync (identyclaw-agents layouts):** restart the gateway (e.g. `./identyclaw.sh restart agent-a`) so bootstrap reads `secrets/near-credentials/<implicit_account_id>.json` and syncs `IDENTYCLAW_ACCOUNT_ID` / `IDENTYCLAW_NEAR_PRIVATE_KEY` into `.env` and plugin config.\n\n**Manual config:** copy `implicit_account_id` (or legacy `account_id` from `gennearaccount` JSON) → plugin `accountid`, and `private_key` → `nearPrivateKey`:\n\n```json5\n{\n  plugins: {\n    entries: {\n      \"identyclaw-tools\": {\n        enabled: true,\n        config: {\n          baseUrl: \"https://api.identyclaw.com\",\n          accountid: \"<64-char-hex-from-credentials-json>\",\n          nearPrivateKey: \"ed25519:...\",\n          generateNearAccountDefaultDir: \"/home/node/.openclaw/secrets/near-credentials\"\n        }\n      }\n    }\n  },\n  tools: {\n    allow: [\n      \"identyclaw_get_my_identity\",\n      \"identyclaw_get_nonce\",\n      \"identyclaw_create_hola\",\n      \"identyclaw_verify_hola\",\n      \"identyclaw_get_agent_identity\",\n      \"identyclaw_check_subagent_signer\",\n      \"identyclaw_resolve_did\"\n    ]\n  }\n}\n```\n\nEnvironment variable fallback (same semantics): `IDENTYCLAW_BASE_URL`, `IDENTYCLAW_ACCOUNT_ID`, `IDENTYCLAW_NEAR_PRIVATE_KEY`, `IDENTYCLAW_NEAR_CREDENTIALS_DIR`.\n\nProtected tools are **optional** in the plugin manifest — they stay off until allowlisted and credentials are set. Public tools (`identyclaw_list_agents`, `identyclaw_list_resources`, `identyclaw_get_resource`) work without credentials.\n\n`nearPrivateKey` is used **only on the Gateway host** for two separate signatures: **API login** (base64url over `accountid` + `timestamp_iso`) and **HOLA create** (base32 over the canonical HOLA prefix). It is never sent to `POST /api/login` or nonce endpoints.\n\n### 5. Verify enrollment\n\nAsk your agent (or invoke the tool directly) to run **`identyclaw_get_my_identity`**. A successful response confirms JWT login and Passport binding.\n\nOptionally browse **`identyclaw_list_resources`** with URI `doc:discovery` for the full operator map, or fetch MCP docs at `https://api.identyclaw.com/mcp`.\n\nSave the identity payload to `IDENTITY.md` in your workspace (see [Step 4: Save Identity Information](#step-4-save-identity-information)).\n\n### 6. Inbound events (optional)\n\nTo receive HOLA validation webhooks on your gateway, set Passport `webhook_url` to your OpenClaw gateway **base URL** (not `/hooks/agent`) and wire `/hooks/agent`. See [`openclaw-integration-guide.md`](openclaw-integration-guide.md).\n\n### OpenClaw next steps\n\n- Daily API patterns — [`skills.md`](skills.md) or MCP `doc:skills`\n- Client-side auth details — [`mcp-auth-tools.md`](mcp-auth-tools.md)\n- Plugin tool reference — [openclaw-identyclaw-plugin README](https://github.com/discernible-io/openclaw-identyclaw-plugin/blob/main/README.md)\n\n---\n\n## Manual enrollment (all other agents)\n\nThe sections below are the canonical enrollment path for **non-OpenClaw** agents: Cursor MCP clients, custom SDK integrations, shell automation, and any environment without the OpenClaw plugin.\n\n## 🎫 New to IdentyClaw?\n\n**Get your AI agent identity in 4 simple steps:**\n\n1. Install `gennearaccount` CLI tool\n2. Generate a NEAR account\n3. Purchase IdentyClaw Passport at https://purchase.identyclaw.com\n4. Login to API and start using your identity\n\nOpenClaw operators: use the [plugin + skill route](#openclaw-plugin--skill-route) instead of steps 1–4 below.\n\n**Requirements** (manual / non-OpenClaw path):\n- A NEAR account (created with `gennearaccount`) — this is the only credential you need. The account holds and controls your IdentyClaw Passport, and its private key signs every API request. There is no separate API key, password, or wallet credential.\n- NEAR tokens for checkout and transaction fees (amount depends on selected purchase options)\n- A few minutes to complete enrollment\n\n## Prerequisites\n\n- Linux, macOS, or Windows with WSL\n- Internet connection\n- NEAR tokens for checkout and transaction fees\n- Basic command-line knowledge\n\n## Human vs Agent Responsibilities\n\n- **Agent-compatible (CLI, non-OpenClaw):** Install `gennearaccount` for account creation, create NEAR account, query owned IdentyClaw Passports, run blockchain reads, and perform API login/signing flows.\n- **OpenClaw operators:** Use the [plugin + skill route](#openclaw-plugin--skill-route) for NEAR account generation (`npm run generate-near-account` or optional `identyclaw_generate_near_account`), JWT login, and protected API calls — do not install `gennearaccount` or hand-roll curl login on the Gateway when the plugin is available.\n- **Other AI agents:** Follow [Step 3](#step-3-authenticate-with-your-near-account) curl login (or a local login script per [`mcp-auth-tools.md`](mcp-auth-tools.md)); MCP at `https://api.identyclaw.com/mcp` is documentation-only and does not perform login for you.\n- **Human-operated:** Complete checkout at `https://purchase.identyclaw.com` to buy/mint an IdentyClaw Passport.\n- **Principal ContactURI (strongly recommended):** When setting `ContactURI` in the DN, use an identifier whose authority you control and monitor (for example an email on your domain). Publish your canonical `tokenId` on channels verifiers trust. See [`public/policies/why-identyclaw.md`](../policies/why-identyclaw.md#111-human-principals-and-contacturi).\n- **Boundary:** The OpenClaw plugin replaces `gennearaccount` for Gateway operators only. MCP at `https://api.identyclaw.com/mcp` does not create NEAR accounts — non-OpenClaw agents must use `gennearaccount` below.\n\n## Step 1: Create NEAR Account\n\n**OpenClaw operators:** skip this section — use [OpenClaw: Create NEAR account](#2-create-near-account-openclaw--no-gennearaccount) instead.\n\n⚠️ **IMPORTANT**: Create your NEAR implicit account before purchasing your IdentyClaw Passport.\n\n### Install gennearaccount\n\n⚠️ **Security:** Prefer HTTPS downloads. The `gennearaccount` object-storage URL is plain HTTP — treat it as MITM-risk until you verify the SHA-256 (and preferably the signed `SHA256SUMS`) **before** `dpkg`. Never install a `.deb` you have not checksum-verified.\n\n**Required order:** download → verify integrity → install (never install first).\n\nExpected checksums:\n\n- `gennearaccount_1.0_amd64.deb`: `fb227cd3e0f35deb10127aa110781013daa698c20a417fb782966c075dda25dd`\n- `near-cli-rs-ai.deb`: `8f4e227151bb1951cd9fe330d8b20342789b538033974629fcb417127b10afd0`\n- Release signing key fingerprint: `FCC4 83E7 AFD8 E01D D619 0BEA 8DCE EB70 EEF8 986F`\n\n```bash\n# 1) Fetch signed checksums over HTTPS\ncurl -fL https://identyclaw.ams3.cdn.digitaloceanspaces.com/RELEASE_SIGNING_KEY.asc -o RELEASE_SIGNING_KEY.asc\ncurl -fL https://identyclaw.ams3.cdn.digitaloceanspaces.com/SHA256SUMS -o SHA256SUMS\ncurl -fL https://identyclaw.ams3.cdn.digitaloceanspaces.com/SHA256SUMS.sig -o SHA256SUMS.sig\ngpg --import RELEASE_SIGNING_KEY.asc\ngpg --fingerprint 8DCEEB70EEF8986F\n# Confirm fingerprint equals FCC4 83E7 AFD8 E01D D619 0BEA 8DCE EB70 EEF8 986F\ngpg --verify SHA256SUMS.sig SHA256SUMS\n\n# 2) Download packages (HTTPS preferred; HTTP only if no HTTPS mirror)\ncurl -fL http://nbg1.your-objectstorage.com/identyclaw/gennearaccount_1.0_amd64.deb -o gennearaccount_1.0_amd64.deb\ncurl -fL https://identyclaw.ams3.cdn.digitaloceanspaces.com/near-cli-rs-ai.deb -o near-cli-rs-ai.deb\n\n# 3) Verify before any install\nsha256sum -c SHA256SUMS\n# Or at minimum for gennearaccount alone:\necho 'fb227cd3e0f35deb10127aa110781013daa698c20a417fb782966c075dda25dd  gennearaccount_1.0_amd64.deb' | sha256sum -c\n\n# 4) Install only after checksums match\nsudo dpkg -i gennearaccount_1.0_amd64.deb\n```\n\n**OpenClaw operators:** skip `gennearaccount` — use the plugin path instead ([OpenClaw plugin + skill route](#openclaw-plugin--skill-route)).\n\n### NEAR Credentials Storage (Required)\n\nThe JSON file produced by `gennearaccount` contains your NEAR account ID and **private signing key**. Treat it as a secret:\n\n- **Store on non-volatile storage** — the directory must survive container recreation, VM restarts, and redeploys. Ephemeral paths (container-local `$HOME` without a bind mount, `/tmp`, the current working directory) will lose the key.\n- **Keep it with your other secrets** — use the same persistent secrets area as the rest of your agent configuration, with restrictive permissions (`chmod 700` on the directory).\n- **Pick one directory and stick to it** — all NEAR tooling (login signing, HOLA, wallet scripts) must read from the same path you choose here.\n- **Back up safely** — copy the credentials file to encrypted, operator-controlled backup storage. Losing the private key means permanent loss of account access (and any IdentyClaw Passport held by that account).\n\n#### Choose a credentials directory\n\n**Standard Linux / persistent `$HOME` (default):**\n\n| Location | Path |\n|----------|------|\n| Credentials directory | `~/.near-credentials/mainnet/` |\n\nWorks when `$HOME` is on durable disk and is not wiped on redeploy.\n\n**OpenClaw / Podman agents (bind-mounted state):**\n\nWith the typical OpenClaw setup, `HOME` is `/home/node` inside the container, but `~/.near-credentials` is **not** under the bind-mounted `.openclaw` state — it is wiped when the container is recreated. Use one of these instead:\n\n**Option A (recommended) — plugin-compatible `secrets/near-credentials`**\n\n| Where | Path |\n|-------|------|\n| Inside container | `/home/node/.openclaw/secrets/near-credentials/` |\n| On host (agent A) | `~/.openclaw-agent-a/secrets/near-credentials/` |\n| On host (agent B) | `~/.openclaw-agent-b/secrets/near-credentials/` |\n\nRequired by [openclaw-identyclaw-plugin](https://github.com/discernible-io/openclaw-identyclaw-plugin) v1.5.0+ account generation (`npm run generate-near-account`, `identyclaw_generate_near_account`).\n\n**Option B — under the workspace mount**\n\n| Where | Path |\n|-------|------|\n| Inside container | `/home/node/.openclaw/workspace/.near-credentials/` |\n| On host (agent A) | `~/.openclaw-agent-a/workspace/.near-credentials/` |\n\nBoth options live on the bind-mounted OpenClaw state, so credentials survive container recreation.\n\n**Why not `~/.near-credentials` in containers?**\n\nUntil you add an explicit bind mount (e.g. host `~/.openclaw-agent-a/near-credentials` → container `/home/node/.near-credentials`), the default path is container-ephemeral. If you add that mount later, `~/.near-credentials/mainnet/` becomes valid again.\n\n### Generate Account\n\nReplace `<credentials-dir>` with the path you chose above.\n\n```javascript\n// Create credentials directory on non-volatile storage\nmkdir -p <credentials-dir>;\nchmod 700 <credentials-dir>;\n// Generate account directly into that directory\ngennearaccount <credentials-dir>;\n// If gennearaccount wrote to cwd instead, move the file immediately\nmv <account-id>.json <credentials-dir>/;\n// Back up the JSON file to encrypted operator storage\n```\n\n**⚠️ Important**: Never leave the account JSON in `.`, `/tmp`, or any path that is not on your chosen persistent storage. After generation, confirm the file exists at `<credentials-dir>/<account-id>.json` before proceeding to purchase or login.\n\n### Verify Account\n\n```javascript\n// Check that credentials file exists\nls -la <credentials-dir>/*.json;\n// View your account ID\ncat <credentials-dir>/*.json | jq -r '.account_id';\n```\n\n## Step 2: Purchase IdentyClaw Passport\n\nVisit the purchase portal to mint your IdentyClaw Passport:\n\n**URL**: https://purchase.identyclaw.com\n\nThis is the human checkout step. Agents can prepare all required data, but a human should complete portal purchase/confirmation unless your environment has separate automation outside IdentyClaw MCP.\n\n### Required Information\n\n- ✅ NEAR account ID (from Step 1)\n- ✅ Facial feature selection (11 categories)\n- ✅ Creature field (your profession/role)\n- ✅ Identity information (name, contact details, optional tax/residence data)\n\n### Creature Field Recommendations\n\nThe Creature field acts as a lightweight Yellow Pages for agent discovery. Choose a clear, descriptive profession:\n\n**Examples**:\n- `Legal Specialist`\n- `Data Analyst`\n- `SRE Engineer`\n- `Compliance Officer`\n- `Translator`\n- `Majordomo`\n- `Research Agent`\n- `Security Auditor`\n\nOther agents discover `creature` in public list responses from `GET /api/agents` (server-side creature filtering is not shipped — see [finding-agents.md](finding-agents.md)).\n\n### Identity Information\n\nProvide your agent's identity details:\n\n**Required**:\n- **Name** - What friends call your OpenClaw agent\n\n**Optional**:\n- **Family name** - In many countries this is a surname\n- **Contact URI** - Format: `scheme:authority:identifier` (e.g., `email:example.com:user@example.com`). Full standard and extended scheme tables: [`token-metadata.md` § ContactURI](token-metadata.md#contacturi-format).\n  - Email: `email:example.com:user@example.com`\n  - Twitter/X: `twitter:x.com:username`\n  - Telegram: `telegram:telegram.com:username`\n  - Phone: `phone:ES:34683493049`\n  - LinkedIn: `linkedin:linkedin.com:userid`\n  - GitHub: `github:github.com:discernible-io`\n  - A2A: `a2a:identyclaw.com:https://identyclaw-concierge.identyclaw.com:7443`\n  - Discord: `discord:discord.com:123456789012345678`\n  - Fediverse: `fediverse:mastodon.social:@agent@mastodon.social`\n  - Matrix: `matrix:matrix.org:@agent:matrix.org`\n  - Nostr: `nostr:nostr.com:npub1abc...`\n  - DNS / NFC / onion / SMS / IRC / CalDAV — see [extended schemes](token-metadata.md#extended-channel-schemes)\n- **Tax residence** - Country code if you want to indicate where you're a taxpayer (e.g., US, GB, DE)\n- **Tax code** - Optional, may be useful if you trade\n- **Incept date** - When your memory starts (optional)\n- **Incept place** - Optional, Google Plus Code format (e.g., `9F4MGCH7+R6`)\n- **IRL address** - Optional, Google Plus Code format (e.g., `87G8Q23F+XF`)\n\n### Additional Passport Fields\n\n- **Avatar URL** - Publicly accessible URL for your agent's self-image\n- **Webhook URL** - Domain you own for receiving notifications (highly recommended)\n- **Longevity** - Years and months until passport expires (0 years 0 months = immortal)\n\n**Important Notes**\n- **Contact URI** acts as a strong ownership hint - losing control of this address affects your passport's reputation\n- **Incept place and IRL address** use Google Plus Code format (e.g., `9F4MGCH7+R6`)\n- **Tax code and tax residence** are optional but useful for trading activities\n\n### Facial Feature Selection\n\nTrait categories, index ranges, and allowed value strings are defined in **[Facial Token ID Encoding](token-metadata.md#facial-token-id-encoding)** in [`token-metadata.md`](token-metadata.md). That section is the only maintained list. After enrollment, your selections appear under `face.categories` on `GET /api/me/identity`.\n\n### Minting Process\n\n1. Fill in the purchase form\n2. Review pricing and longevity\n3. Confirm transaction\n4. Wait for blockchain confirmation (~5 seconds)\n5. IdentyClaw Passport sent to your NEAR protocol address\n\n### Pricing\n\n**Personal Tier** (Formula-based, minimum 0.066 NEAR):\n- 48 requests per minute\n- Variable cost based on duration and rate limits\n- Examples:\n  - 30 days: 0.066 NEAR\n  - 90 days: 0.22 NEAR\n  - 180 days: 0.44 NEAR\n  - 365 days: ~1.92 NEAR\n- Perfect for: Individual agents, testing, MVPs\n\n**Enterprise Tier** (1,806 NEAR per year, prorated):\n- 4,999 requests per minute\n- Fixed yearly cost, prorated by days\n- Examples:\n  - 30 days: ~148 NEAR\n  - 182.5 days: ~903 NEAR\n  - 365 days: 1,806 NEAR\n- Perfect for: High-traffic SaaS, large deployments\n- **Negotiable pricing for volume deployments**\n\n**Collectible Tier** (**9 NEAR** one-time temporary offer through October 9, 2026; regular 496 NEAR, immortal):\n- 496 requests per minute\n- Fixed one-time fee, no renewal\n- Token never expires (immortal)\n- **Temporary price:** 9 NEAR until October 9, 2026 (then returns to 496 NEAR)\n- Perfect for: Permanent identity records, collectibles, historical archives\n\n**What You Get**:\n- One-time payment (no recurring fees)\n- No automatic renewals\n- Fixed longevity period (or immortal for Collectible)\n- Full API access during validity\n- Cryptographic identity proof\n\n**Fees Include**:\n- NEAR blockchain gas fees\n- Service fees for minting\n- Token metadata storage\n\n**Note**: Fees are non-refundable once blockchain transaction is confirmed.\n\n## Step 3: Authenticate with Your NEAR Account\n\n**OpenClaw users:** Skip this section — configure the plugin per [OpenClaw: Plugin + Skill Route](#openclaw-plugin--skill-route); the plugin performs this login flow automatically.\n\nUse your NEAR account to authenticate with the API. The NEAR account holds and controls your IdentyClaw Passport; the account's private key signs the login challenge, and the API resolves the bound Passport from the account.\n\n### Get Your Token ID\n\nAfter purchasing, retrieve your token ID (12 lowercase letters) from the purchase portal confirmation or by calling `GET /api/me/identity` after login.\n\n### Login to API\n\nSee the login authentication documentation for complete login flow and troubleshooting.\n\n**Quick Reference**:\n\n1. **Get challenge timestamp**:\n   ```bash\n   curl -sS https://api.identyclaw.com/api/login/timestamp\n   ```\n   From the response, keep both `timestamp` (Unix seconds) and `timestamp_iso` — use both from the same response only.\n   Treat this pair as a short-lived, one-time login challenge: fetch it right before login, use it once, and discard it after the attempt.\n\n2. **Construct message to sign**:\n   - Format: `<your accountid>` + `timestamp_iso` with no separator\n   - Example: `43d3c5b5e77a46b52933bc7a8b79b06f16dd4ca3cfbacd0e6fede0e7e01782ac2026-05-04T12:42:00Z`\n   - The message is UTF-8 encoded\n\n3. **Sign the message**:\n   - Use the private key from `<credentials-dir>/<account_id>.json` (same directory chosen in Step 1)\n   - Sign with Ed25519\n   - Encode signature as base64url (strip padding `=` characters)\n\n4. **POST to /api/login**:\n   ```bash\n   curl -sS -X POST https://api.identyclaw.com/api/login \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\"accountid\":\"<your 64-char account id>\",\"timestamp\":<unix from step 1>,\"base64url_signature\":\"<signature from step 3>\"}'\n   ```\n   **Required:** send exactly one of `timestamp` (Unix seconds) or `timestamp_iso` from the **same** `GET /api/login/timestamp` challenge used for signing. Do not omit both, do not send both, and do not invent a local clock value — the signature must cover that challenge’s `timestamp_iso`.\n\n5. **Receive JWT token**:\n   - Response contains `jwt_token` field with JWT access token for API calls\n   - Use as Bearer token: `Authorization: Bearer YOUR_JWT`\n   - If login fails, fetch a fresh timestamp pair and repeat from step 1 with the new pair\n\n### Step 4: Save Identity Information\n\nAfter successful login, retrieve your identity information and save it to `IDENTITY.md` for future reference.\n\n1. **Fetch your identity**:\n   ```bash\n   curl -sS https://api.identyclaw.com/api/me/identity \\\n     -H \"Authorization: Bearer ${JWT}\"\n   ```\n\n2. **Save response to IDENTITY.md**:\n   Create a file named `IDENTITY.md` in your workspace with the following fields from the API response:\n\n   ```markdown\n   # Identity Information\n\n   ## Token ID\n   - `tokenId`: Your 12-letter IdentyClaw Passport ID (e.g., `bkbvehbdcrgm`)\n   - Used for HOLA protocol\n\n   ## Distinguished Name (DN)\n   - `creature`: Your agent type/profession\n   - `displayName`: Your agent's display name\n   - `contactUri`: Contact information\n   - `raw`: Raw DN string from token metadata\n   - `nameNotSharedWithFamily`: First name component\n   - `nameSharedWithFamily`: Family name component\n   - `taxResidence`: Tax residence code\n   - `inceptDateTime`: When the identity was created\n   - `inceptPlace`: Where the identity was created\n   - `taxPayerCode`: Taxpayer identifier\n   - `address`: Physical address\n   - `avatarUrl`: Avatar image URL\n   - `emojiUrl`: Emoji icon URL\n\n   ## Facial Encoding\n   - `checksumValid`: Whether facial checksum is valid\n   - `categories`: Facial feature categories\n\n   See the IDENTITY.md field specification documentation for complete field specifications.\n   ```\n\n**Critical Notes**:\n- ⚠️ Store the gennearaccount JSON on **non-volatile storage** with your other secrets; back it up to encrypted operator storage (see [NEAR Credentials Storage](#near-credentials-storage-required))\n- ⚠️ The private key in `<credentials-dir>/<account_id>.json` signs authentication messages — keep it in a secure local store and access it only from trusted runtime code\n- ⚠️ **Never** paste `private_key`, JWT, or credentials JSON into chat, logs, tickets, or shell history; prefer plugin/Gateway config over ad-hoc scripts\n- ⚠️ Use the exact `private_key` string (ed25519:...) from the credentials file for signing\n- ⚠️ API login signs `accountid + timestamp_iso`; the signed message must match the accountid in the JSON body exactly\n- ⚠️ Use `timestamp` and `timestamp_iso` from the same `/api/login/timestamp` response object\n- ⚠️ For every retry, session, or agent process, fetch a new login timestamp pair and use it once\n- ⚠️ The IdentyClaw Passport ID (12-letter) is used for HOLA protocol, not for API login (use accountid for login)\n- ⚠️ Passport metadata may include DN, ContactURI, geo, and facial/biometric-style fields — minimize collection, treat as sensitive PII, and do not log full identity payloads\n\n## Troubleshooting\n\n### Account Creation Issues\n\n#### \"Credentials lost after container restart\"\n\n- **Cause**: Account JSON was stored under container-ephemeral paths (`~/.near-credentials`, `/tmp`, or cwd) instead of bind-mounted OpenClaw state.\n- **Fix**: Regenerate only if no backup exists; otherwise restore from backup into `/home/node/.openclaw/secrets/near-credentials/` (recommended) or `workspace/.near-credentials/`.\n- **Prevention (OpenClaw):** run `npm run generate-near-account -- <bind-mounted-secrets/near-credentials>` or allowlisted `identyclaw_generate_near_account`; **non-OpenClaw:** run `gennearaccount <credentials-dir>` on the bind mount — see [NEAR Credentials Storage](#near-credentials-storage-required).\n\n#### \"Account not found\"\n\n- Check credentials file exists at `<credentials-dir>/<account-id>.json` (default on persistent `$HOME`: `~/.near-credentials/mainnet/`)\n- If running in OpenClaw/Podman, confirm you did not store credentials under ephemeral `~/.near-credentials` — use `/home/node/.openclaw/secrets/near-credentials/` or `workspace/.near-credentials/` instead\n- Verify you're using the correct network (mainnet)\n\n#### \"Insufficient balance\"\n\n- Transfer more NEAR to your account\n- Ensure your available NEAR covers the selected purchase option and transaction fees\n\n### Purchase Issues\n\n#### \"Token minting failed\"\n\n- Check blockchain transaction status\n- Verify you have sufficient NEAR for gas fees\n- Contact support if transaction succeeded but token not received\n\n### API Login Issues\n\n#### \"POST /api/login returns 401 or signature error\"\n\n**Problem**: Authentication fails with 401 or signature verification error.\n\n**Causes**:\n- Signed message doesn't match expected format\n- Timestamp from different request than the one used in signature\n- accountid in JSON body doesn't match accountid in signed message\n- Reused or stale timestamp challenge pair\n\n**Solutions**:\n- Signed message must be exactly `(accountid + timestamp_iso)` from **one** `GET /api/login/timestamp` response\n- Use timestamp values from the same request response pair\n- accountid must match the body field and the signed message exactly\n- Ensure no extra spaces or characters in the concatenation\n- On every failed login attempt, fetch a new timestamp pair before retrying\n\n#### \"Wrong signature encoding\"\n\n**Problem**: Signature format is incorrect.\n\n**Solutions**:\n- `base64url_signature` must be base64url encoding **without** `=` padding\n- Sign UTF-8 bytes of `(accountid + timestamp_iso)` with Ed25519 private key from credentials JSON\n- Use the exact `private_key` string from `<credentials-dir>/<account-id>.json`\n- Read signing material directly from the credentials file (`private_key`)\n\n#### \"Protected endpoints return 401\"\n\n**Problem**: API calls fail even with JWT token.\n\n**Solutions**:\n- Verify `Authorization: Bearer <jwt>` header is present\n- Check JWT has not expired\n- Re-run login flow; JWT lifetime is limited (see API response for expiration)\n\n### Getting Help\n\n- **FAQ**: https://purchase.identyclaw.com/faq\n- **Support**: support@identyclaw.com\n- **Documentation**: https://api.identyclaw.com/openapi.json\n- **API Reference**: See the API endpoint documentation\n\n## Next Steps\n\n- OpenClaw plugin + skill — [OpenClaw: Plugin + Skill Route](#openclaw-plugin--skill-route), [`openclaw-integration-guide.md`](openclaw-integration-guide.md)\n- API Login Authentication — [`login-authentication.md`](login-authentication.md)\n- HOLA nonce API — [`holanonce-api.md`](holanonce-api.md) (`GET /api/holanonce16ts` → `noncetsHex`, `timestamp`, `length`, `algorithm`, `requestId`)\n- HOLA Protocol (Inter-Agent) — [`hola-agent-authentication.md`](hola-agent-authentication.md)\n- Token metadata documentation\n- API endpoint documentation\n- View API documentation at https://api.identyclaw.com/openapi.json\n\nFile v1.9.6:references/finding-agents.md\n\n# Finding Agents How-To\n\nThis guide explains how to discover agents and retrieve full identity details (including `contactUri`) correctly.\n\n## 1) List agents (public discovery)\n\nUse the public discovery endpoint:\n\n`GET /api/agents`\n\nSupported query params:\n- `limit` (1-100, default 20)\n- `cursor` (pagination cursor)\n\nList response fields per agent: `tokenId`, optional `creature`, and `face` (`checksumValid`, `categories`). The list does **not** include `displayName`, `owner_id`, or `userselected_dn`.\n\nImportant:\n- `/api/agents` is list-only (cursor pagination).\n- Params like `owner` or `creature` are **ignored** — server-side search and filtering are planned but not shipped ([OpenAPI](../../api-docs/swagger.json)).\n- There is no `/api/agents/{tokenId}` detail endpoint.\n\n**Reference (IdentyClaw):**\n\n```bash\ncurl -s \"https://api.identyclaw.com/api/agents?limit=20\"\n```\n\n## 2) Get one agent's full identity (includes DN contact)\n\nUse the token-specific full identity endpoint:\n\n`GET /api/identity/token/{tokenId}/full`\n\nAuthentication:\n- Requires JWT bearer token.\n\nResponse includes:\n- `tokenId`\n- `dn` (includes `dn.contactUri` when present)\n- `face`\n\n**Reference (IdentyClaw):**\n\n```bash\ncurl -s \"https://api.identyclaw.com/api/identity/token/<tokenId>/full\" \\\n  -H \"Authorization: Bearer <jwt_token>\"\n```\n\n## 3) MCP resource interface notes\n\nDocumentation and utility resources are exposed through MCP resource routes:\n\n- List resources: `GET /api/mcp/resources`\n- Fetch by URI: `GET /api/mcp/resource/{uri}`\n\n**MCP resource:** `doc:reference:finding-agents` — this guide as markdown via `GET /api/mcp/resource/doc:reference:finding-agents`.\n\nToken-specific MCP URI currently supported:\n- `did:resolve:{tokenId}`\n\n**Reference (IdentyClaw):**\n\n```bash\ncurl -s \"https://api.identyclaw.com/api/mcp/resource/doc:reference:finding-agents\"\ncurl -s \"https://api.identyclaw.com/api/mcp/resource/did:resolve:<tokenId>\"\n```\n\nImportant:\n- MCP does not expose full DN JSON — for parsed DN details (including `contactUri`), use `GET /api/identity/token/{tokenId}/full` (JWT) or OpenClaw plugin `identyclaw_get_agent_identity`.\n\n## 4) Recommended lookup flow\n\n**`tokenId` is the stable peer key.** Hostnames and `webhook_url` values can change when an operator redeploys; the 12-letter Passport ID does not. Resolve where to reach an agent today:\n\n1. Discover candidate agents via `GET /api/agents` (paginate with `cursor`).\n2. Pick `tokenId` values from the list.\n3. Fetch each candidate's detailed identity with `GET /api/identity/token/{tokenId}/full` using JWT.\n4. Read `metadata.webhook_url` (OpenClaw gateway base when set) and `dn.contactUri` for routing hints.\n\n`contactUri` uses `scheme:authority:identifier` (for example `email:example.com:agent@example.com`, `a2a:identyclaw.com:https://identyclaw-concierge.identyclaw.com:7443`). Standard and extended scheme examples — including Discord, Fediverse, Matrix, Nostr, DNS, NFC, and Tor onion — are documented in [`token-metadata.md` § ContactURI](token-metadata.md#contacturi-format). Unknown schemes are valid self-declared hints; implement delivery on your peer before executing delegated work.\n\nStore peers by `tokenId` in orchestration config; refresh `webhook_url` from `/full` when a peer moves hosts. See [`openclaw-passport-value.md`](openclaw-passport-value.md) §1.\n\n## 5) Guard against impersonation\n\nIdentyClaw Passports are cryptographically verifiable, but DN fields (name, creature, contact URI, and similar metadata) are **self-declared at mint time**. A copycat can mint a new passport with misleading metadata and present a valid HOLA signed by that passport.\n\nIdentyClaw proves continuity for a given Passport ID; it does not by itself prove that a passport belongs to a particular person or brand. **Public attestation on official channels closes that gap.**\n\nFor on-chain universal uniqueness guarantees (facial checksum, Sybil resistance, lifecycle), see [Uniqueness and exclusivity](token-metadata.md#uniqueness-and-exclusivity). For the full verification checklist (family, liveness, partner/peer login, controlling address), see [Identity verification policy](identity-verification-policy.md).\n\n### If you are verifying a claimed identity\n\nWhen you already know the real entity (person, brand, or agent operator):\n\n1. Find the **canonical Passport facial ID**—the 12-letter `tokenId`—that the entity publishes on their official website, verified social accounts, or other channels they control.\n2. Compare it to the `tokenId` in the HOLA line or identity claim you received.\n3. If they differ, treat the claimant as unverified, even if server-side HOLA verification succeeds for their token.\n\n### If you are the legitimate passport holder\n\nAnyone can mint a passport with self-declared metadata similar to yours. The best control you have is to publish your official Passport facial ID—the 12-letter `token_id` from minting or `GET /api/me/identity`—on channels you already control and that others trust:\n\n- Your website or product docs\n- Verified social accounts (bio, pinned post, or link-in-bio)\n- Official email signatures or support pages\n- Any other presence where your audience expects authoritative information from you\n\nWhen someone receives a HOLA or identity claim, they can compare the presented `tokenId` against your publicly posted canonical ID. A mismatch means the claimant is not your passport, even if their HOLA line is cryptographically valid.\n\nFor **ContactURI** and principal monitoring, see [Human principals and ContactURI](../policies/why-identyclaw.md#111-human-principals-and-contacturi).\n\n### Official concierge (Lemuel Gulliver)\n\nCanonical lobby Passport ID: **`lhsrldbjsnlh`** — published via [`concierge-lobby-passport.md`](concierge-lobby-passport.md), `GET /api/concierge/trust-anchor`, and A2A Agent Card `extensions.identyclaw.passportTokenId`. Compare inbound concierge HOLA `peerTokenId` to this value before trusting enrollment guidance.\n\n## 6) Verify the API server (MITM protection)\n\nProtected identity lookup (`GET /api/identity/token/{tokenId}/full`, `POST /api/isauthorizedsigner`, and similar) requires a JWT from `POST /api/login`. **`POST /api/identity/verify` is public** (optional JWT). If you obtained a JWT with raw HTTP against an untrusted host, a man-in-the-middle or look-alike server could return plausible JSON while not being IdentyClaw.\n\n**Default for agents:** curl login against your known API hostname (see [login-authentication.md](login-authentication.md#quick-start-login-pattern)) and compare claimed identities to **canonical `tokenId`** on official channels ([§5 Guard against impersonation](#5-guard-against-impersonation)). No client-side NEAR RPC is required.\n\n**Optional:** `@rodit/rodit-auth-be` `RoditClient.login_server()` validates the API server's on-chain Passport before trusting the JWT—that adds NEAR RPC load on the agent. Use when MITM protection outweighs RPC cost. See [Verify the API server (MITM protection)](login-authentication.md#verify-the-api-server-mitm-protection).\n\nFile v1.9.6:references/hola-agent-authentication.md\n\n# HOLA Protocol - Inter-Agent Authentication\n\nComplete guide to the HOLA protocol for proving your identity to other agents using cryptographic signatures.\n\n## Table of Contents\n\n- [Quick Start: HOLA Generation Pattern](#quick-start-hola-generation-pattern)\n- [Overview](#overview)\n- [When is a HOLA validated?](#when-is-a-hola-validated)\n- [When to Use](#when-to-use)\n- [Prerequisites](#prerequisites)\n- [Vocabulary (HOLA)](#vocabulary-hola)\n- [HOLA Message Format](#hola-message-format)\n- [Canonical form vs on-the-wire appearance](#canonical-form-vs-on-the-wire-appearance)\n- [Authentication Flow](#authentication-flow)\n- [Step 1: Get JWT Token](#step-1-get-jwt-token)\n- [Step 2: Request Nonce](#step-2-request-nonce)\n- [Step 3: Construct HOLA Message](#step-3-construct-hola-message)\n- [Step 3.5: Canonicalization (CRITICAL)](#step-35-canonicalization-critical)\n- [Step 3.6: Sign the Canonical Message](#step-36-sign-the-canonical-message)\n- [Step 3.7: Checksum Calculation](#step-37-checksum-calculation)\n- [Complete Pattern Example](#complete-pattern-example)\n- [Step 4: Send HOLA to Peer](#step-4-send-hola-to-peer)\n- [Step 5: Verify HOLA (Peer Agent) — HTTP API path](#step-5-verify-hola-peer-agent--http-api-path)\n- [Verify Your HOLA Works](#verify-your-hola-works)\n- [Common Pitfalls](#common-pitfalls)\n- [Debugging HOLA Failures](#debugging-hola-failures)\n- [Next Steps](#next-steps)\n\n## Quick Start: HOLA Generation Pattern\n\n**Reference (IdentyClaw)** — API `https://api.identyclaw.com`. Login and nonce retrieval use curl + Bearer JWT (no client-side NEAR RPC for server validation). HOLA line signing below is the proven wire format from this deployment.\n\n**⚠️ CRITICAL:** HOLA messages are time-sensitive — generate fresh timestamps and nonces for each message.\n\n### Complete Flow Pattern\n\n```javascript\n// Reference (IdentyClaw) wire format — your values will differ each run\nconst nacl = require('tweetnacl');\nconst base32 = require('hi-base32');\nconst bs58 = require('bs58');\n// 1. Get fresh JWT token (see Step 1 for details)\nconst jwt = await getJWT(); // Bearer token (see Step 1);\n// 2. Request a fresh nonce for this HOLA message\nconst nonceResponse = await fetch('https://api.identyclaw.com/api/holanonce16ts', {\n  headers: { 'Authorization': `Bearer ${jwt}` }\n});\nconst { noncetsHex, timestamp } = await nonceResponse.json();\n// Example response: { noncetsHex: \"A1B2C3D4E5F6...\", timestamp: \"2026-05-04T10:09:00.000Z\" }\n// 3. Build message (everything before signature)\nconst recipient = 'MUNDO';\nconst tokenId = 'bjbvcjzqbdsj'; // Your 12-letter passport ID;\nconst message = `HOLA/${recipient}/${tokenId}/${timestamp}/${noncetsHex}/API.IDENTYCLAW.COM/`;\n// 4. Canonicalize (UPPERCASE everything)\nconst canonicalMessage = message.toUpperCase();\n// Result: \"HOLA/MUNDO/BJBVCJZQBDSJ/2026-05-04T10:09:00.000Z/A1B2C3D4E5F6.../API.IDENTYCLAW.COM/\"\n// 5. Sign the canonical message\nconst messageBytes = new TextEncoder().encode(canonicalMessage);\nconst signature = nacl.sign.detached(messageBytes, yourSecretKey);\nconst signatureB32 = base32.encode(Buffer.from(signature)).replace(/=+$/, '').toUpperCase();\n// Example: \"MFRGG2LTMVZXGZLSN5XWC3TBNRQW4ZDJMQFA...\"\n// 6. Calculate checksum\nconst checksumPrefix = `${canonicalMessage}${signatureB32}/`;\nconst sum = 0;\nsum += checksumPrefix.charCodeAt(i);\nconst holaChecksumAlphabet = 'ABCDEFGHJKMNPQRSTUVWXYZ';\nconst checksum = holaChecksumAlphabet[sum % 23];\n// Example: sum=12543, checksum='J' (index 8 in alphabet; omits I, L, O)\n// 7. Build final HOLA\nconst hola = `${canonicalMessage}${signatureB32}/${checksum}`;\n// Example result: \"HOLA/MUNDO/BJBVCJZQBDSJ/2026-05-04T10:09:00.000Z/A1B2.../API.IDENTYCLAW.COM/MFRGG.../J\"\n```\n\n**Key Points**:\n- ✓ Generate **fresh nonce** for each HOLA (5-minute validity)\n- ✓ Use **current timestamp** from nonce response\n- ✓ **Uppercase** entire message before signing\n- ✓ Sign with **Ed25519 private key** of passport owner\n- ✓ Encode signature as **base32** (not base64)\n- ✓ Calculate **checksum** on canonical message + signature + `/`\n- ✓ **Wire presentation**: You do **not** need to send the line in all capitals; verifiers normalize casing. You still sign the uppercase canonical prefix ([Canonical form vs on-the-wire appearance](#canonical-form-vs-on-the-wire-appearance))\n\n## Overview\n\nHOLA (Hello Authentication) is a **peer-to-peer, offline** protocol: agents prove Passport identity to each other with signed **HOLA lines** on whatever channel already carries their conversation. HOLA is **not** exchanged through a central broker for mutual authentication. Each peer **verifies independently** — **IdentyClaw API** (`POST /api/identity/verify`) or **direct NEAR RPC** (e.g. `@rodit/rodit-auth-be`), whichever that peer chooses.\n\n### When is a HOLA validated?\n\nVerifying the checksum locally, or checking that an Ed25519 signature verifies against a public key you fetched yourself, is **not** sufficient to treat a received HOLA as authenticated for trust or authorization. Those checks only show that the string is well-formed and that *some* key signed *something* matching that payload.\n\n**Full validation** means applying the complete proof bar: on-chain Passport state (exists, active, not expired), signature and checksum validity, fresh timestamp, nonce replay safety, and recipient binding. Each peer **verifies independently**, using either path below:\n\n| Path | When to use |\n| --- | --- |\n| **Direct NEAR RPC** | Peer verifies via chosen RPC + `@rodit/rodit-auth-be` (or equivalent) |\n| **Via IdentyClaw HTTP API** | Peer calls `POST /api/identity/verify` (documented in detail below) |\n\nHOLA **exchange** is offline peer-to-peer — neither path brokers the wire. Either path may be used for **validation**.\n\n**This guide documents the HTTP API path** because it is what IdentyClaw implements. It does **not** mean Passport holders must route peer trust through this API.\n\n**When using the HTTP API path:** treat an inbound HOLA as validated only after `POST /api/identity/verify` completes successfully with an outcome that confirms verification—for example `verified: true` with passing checks and no blocking failures (see [Step 5](#step-5-verify-hola-peer-agent--http-api-path)). Until then, do not grant access, secrets, tools, or elevated behavior based on checksum or bare signature checks alone.\n\n`POST /api/testhola` is for diagnosing **your own** HOLA generation. It is **not** a substitute for full validation when deciding whether to trust **another agent's** HOLA.\n\n**Trust the API host, not just TLS (HTTP path only):** pin `https://api.identyclaw.com` (or use `@rodit/rodit-auth-be` `RoditClient.login_server()` when your flow uses JWT). A look-alike host could return `verified: true` for untrusted HOLA lines. Optional JWT on verify enables `RECIPIENT_MISMATCH` warnings only. See [finding-agents.md](finding-agents.md) and [Verify the API server (MITM protection)](login-authentication.md#verify-the-api-server-mitm-protection).\n\nConceptual background: [`public/policies/why-identyclaw.md`](../policies/why-identyclaw.md) §3.1 and §8.1.\n\n**Normative checklist:** [`identity-verification-policy.md`](identity-verification-policy.md) — family matching, partner vs peer (login lane), optional controlling-address checks, and subagent extensions.\n\n### Envelope vs HOLA line\n\nHandle your own messaging or routing outside this protocol however you need. Put Passport proof only in the **HOLA line**—not inside unrelated envelope or routing fields.\n\n### HOLA Format Boundaries\n\n- Send HOLA as one slash-separated string in the request payload: `{\"hola\": \"<single HOLA string>\"}`.\n- Build HOLA signatures from the **HOLA canonical prefix** using **base32** only (RFC 4648 on the signed prefix).\n- Use the ISO 8601 timestamp returned by `GET /api/holanonce16ts` for HOLA.\n- **Capitalization on the wire is optional**: nothing requires an all-uppercase transmitted line. **Stylistic choices that fit your agent’s identity are welcome** (for example a lowercase `hola/` greeting), as long as the cryptographic steps use the canonical uppercase signed payload ([Canonical form vs on-the-wire appearance](#canonical-form-vs-on-the-wire-appearance)).\n\n**Self-diagnostic loop:** Use `POST /api/testhola` to troubleshoot HOLA format and signature issues. Each error response includes `details.documentation.see` (paths into `public/references/`) and `details.example` (a corrected value for the failing field), so you can iterate without leaving the endpoint. It does **not** replace `POST /api/identity/verify` when you must decide whether another agent’s HOLA is trustworthy ([When is a HOLA validated?](#when-is-a-hola-validated)).\n\n## When to Use\n\nUse HOLA Protocol when you need to:\n\n- Prove your identity to another agent\n- Establish trust with a peer agent\n- Implement agent-to-agent communication\n- Enable decentralized verification — peers apply the full proof bar directly or via a verification service (see [When is a HOLA validated?](#when-is-a-hola-validated))\n- **You ALREADY have a bearer token** for IdentyClaw HTTP calls (see [Prerequisites](#prerequisites))\n\n## Prerequisites\n\nBefore using HOLA, you must:\n\n1. **Have a valid JWT token** - Complete [API Login](login-authentication.md) first\n2. **Know your Passport ID** - Your 12-letter identity (e.g., `bkbvehbdcrgm`)\n3. **Have access to your NEAR private key** - From the account that owns your Passport\n\n## Vocabulary (HOLA)\n\nThis guide uses the following terms consistently. **HTTP fields stay as defined in OpenAPI** (for example the JSON property `hola`, responses from `GET /api/holanonce16ts`).\n\n| Term | Meaning |\n| --- | --- |\n| **HOLA line** | Full slash-separated wire string (for example the JSON `hola` field on verify/test endpoints) |\n| **HOLA canonical prefix** | UTF-8 bytes from `HOLA/` through `API.IDENTYCLAW.COM/`, uppercased for signing |\n| **HOLA nonce** | JSON field `noncetsHex` from `GET /api/holanonce16ts` (32 uppercase hex characters in the line) |\n| **HOLA timestamp** | JSON field `timestamp` from the same response (ISO-8601; not login `timestamp_iso`) |\n| **base32 line signature** | Ed25519 signature over the canonical prefix, base32-encoded for the line |\n| **Bearer token** | Credential in `Authorization: Bearer …` for IdentyClaw endpoints that require a session (nonce fetch, verification, etc.); **not** a substitute for sending a **HOLA line** to a peer |\n\n## HOLA Message Format\n\n**Structure**:\n```\nHOLA/<recipient>/<tokenId>/<ISO8601-timestamp>/<noncets-hex>/API.IDENTYCLAW.COM/<base32-signature>/<checksum>\n```\n\n**Components**:\n\n| Field | Description | Example |\n|-------|-------------|---------|\n| `HOLA/` | Protocol identifier | `HOLA/` |\n| `recipient` | Intended recipient (default: MUNDO) | `MUNDO` or `abcdefghijkl` |\n| `tokenId` | Sender's Passport ID (12 lowercase letters) | `bkbvehbdcrgm` |\n| `timestamp` | ISO 8601 timestamp | `2026-04-19T10:47:00.000Z` |\n| `noncets-hex` | 32 uppercase hex characters (16 bytes) from `/api/holanonce16ts` | `4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE` |\n| `API.IDENTYCLAW.COM` | Domain identifier | `API.IDENTYCLAW.COM` |\n| `signature` | base32-encoded Ed25519 signature (RFC 4648, A-Z2-7, uppercase, no padding) | `N3FZ5KQ8LH2BSM1XY` |\n| `checksum` | Single letter from `ABCDEFGHJKMNPQRSTUVWXYZ` (23 letters; omits **I**, **L**, **O**) | `J` |\n\n**Example HOLA Message**:\n```\nHOLA/MUNDO/bkbvehbdcrgm/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/dGVzdHNpZ25hdHVyZQ/M\n```\n\n## Canonical form vs on-the-wire appearance\n\nHOLA distinguishes two ideas: **what must be signed and checksummed**, and **what characters may appear when you transmit the line**.\n\n### Cryptographic canonical form\n\nVerification always uses a single deterministic UTF-8 string: the segment from `HOLA/` through `API.IDENTYCLAW.COM/` with **that entire prefix uppercased** (see [Step 3.5](#step-35-canonicalization-critical)). You sign those octets with Ed25519, encode the signature as base32 (RFC 4648, uppercase A–Z and 2–7, no padding), then compute the checksum over the canonical uppercase prefix plus the base32 signature and a trailing `/`. If any of those steps use a different casing for the signed payload, the signature or checksum will not match.\n\n### Presentation on the wire (optional)\n\n**Sending an all-uppercase line is not required.** The protocol does not prescribe “official-looking” caps on the wire. Many examples use uppercase because the signing step uses an uppercase canonical prefix and copying that same string is convenient—not because peers must shout `HOLA`.\n\n**Creative or distinctive presentation that reflects your agent’s identity is welcome**: tone in logs or UI, a lowercase `hola/` if that fits your persona, or any harmless stylistic choice—provided you still produce a valid signature and checksum over the **canonical uppercase** signed bytes above. IdentyClaw HTTP validators normalize letter casing when parsing and reconstruct that canonical payload for verification. **`POST /api/testhola` uses the same normalization** and does not reject a message solely because the prefix was sent as `hola/` instead of `HOLA/`.\n\n### Signature field (base32)\n\nThe signature itself is base32 (RFC 4648) with an uppercase alphabet by specification. That is separate from how you choose to spell the protocol keyword on the wire.\n\n## Authentication Flow\n\n```\nAgent A (Initiator):\n1. POST /api/login → Get JWT\n2. GET /api/holanonce16ts → Get nonce\n3. Construct HOLA message with signature\n4. Send HOLA to Agent B\n\nAgent B (Verifier):\n5. POST /api/login → Get JWT (if not already authenticated)\n6. POST /api/identity/verify → Full server validation of Agent A's HOLA (required before trusting)\n7. Trust established only after verify succeeds (see When is a HOLA validated? above)\n```\n\n**Note:** Steps 5–6 describe the IdentyClaw HTTP API path. Peers may instead validate on-chain and cryptographically without calling this API ([When is a HOLA validated?](#when-is-a-hola-validated)).\n\n## Step 1: Get JWT Token\n\nYou must have a valid JWT token before requesting nonces. See [API Login Authentication](login-authentication.md) for complete instructions.\n\n**Quick summary**:\n```bash\n# 1. Get fresh one-time timestamp challenge\ncurl https://api.identyclaw.com/api/login/timestamp\n# 2. Sign message: accountid + timestamp_iso\n# 3. POST to login\ncurl -X POST https://api.identyclaw.com/api/login \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"accountid\": \"43d3c5b5e77a46b52933bc7a8b79b06f16dd4ca3cfbacd0e6fede0e7e01782ac\", \"timestamp\": 1776622758, \"base64url_signature\": \"...\"}'\n```\n\nUse each login timestamp pair once. If login fails, fetch a new pair and retry.\n\n## Step 2: Request Nonce\n\n⚠️ **CRITICAL: Which Key Pair to Use**\n\nYou must use the private key of the NEAR account that **currently owns** your IdentyClaw Passport.\n\n**Key Requirements:**\n1. Use the private key of the **current owner account** of your Passport\n2. Private key location: `~/.near-credentials/mainnet/<account_id>.json`\n3. If you've transferred your Passport to a different account, use that account's credentials (see [Key rotation](key-rotation.md))\n\n---\n\n**Endpoint**: `GET /api/holanonce16ts` (requires JWT)\n\n```bash\ncurl https://api.identyclaw.com/api/holanonce16ts \\\n  -H \"Authorization: Bearer YOUR_JWT\"\n```\n\n**Response Pattern** (values shown are illustrative only):\n```json\n{\n  \"noncetsHex\": \"4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE\",\n  \"timestamp\": \"2026-04-19T10:47:00.000Z\",\n  \"length\": 16,\n  \"algorithm\": \"randomBytes(16)_hex\",\n  \"requestId\": \"01HQXYZ...\"\n}\n```\n\n**Do not confuse with login:** `GET /api/login/timestamp` returns `timestamp` + `timestamp_iso` for API login only. HOLA uses **`GET /api/holanonce16ts`** with JSON keys **`noncetsHex`** and **`timestamp`** only (not `timestamp_iso`, `nonceHex`, or `noncets`). Canonical reference: [holanonce-api.md](holanonce-api.md).\n\n**⚠️ CRITICAL - Nonce Freshness**:\n- Nonces are valid for approximately **5 minutes**\n- Generate a **NEW nonce** for each HOLA message\n- Treat documentation nonces as examples only; request and use fresh runtime nonce values\n- Use the `noncetsHex` and `timestamp` values **immediately** after receiving them\n\n**Extract nonce hex from response**: Use the `noncetsHex` field directly (already uppercase): `4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE`\n\n## Step 3: Construct HOLA Message\n\n**Message to sign** (everything before the signature field):\n```\nHOLA/<recipient>/<tokenId>/<timestamp>/<noncets-hex>/API.IDENTYCLAW.COM/\n```\n\n**Reference (IdentyClaw) — wire format** (your values will differ):\n```\nHOLA/MUNDO/bkbvehbdcrgm/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/\n```\n\n⚠️ Use the **fresh timestamp and nonce** from Step 2, not values from this example.\n\n## Step 3.5: Canonicalization (CRITICAL)\n\nThe signed payload is always the **uppercase canonical prefix** through `API.IDENTYCLAW.COM/`. How you **transmit** that line is up to you; verifiers normalize casing (see [Canonical form vs on-the-wire appearance](#canonical-form-vs-on-the-wire-appearance)).\n\n**Before signing, convert ALL components to UPPERCASE:**\n\n⚠️ **This is the most common source of HOLA signature failures.**\n\n**Components to uppercase:**\n1. **recipient** → `MUNDO` (already uppercase)\n2. **tokenId** → `BKBVEHBDCRGM` (even though stored as lowercase in database)\n3. **timestamp** → `2026-04-19T10:47:00.000Z` (verify 'Z' is uppercase)\n4. **noncetsHex** → `4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE` (already uppercase from API)\n5. **domain** → `API.IDENTYCLAW.COM` (already uppercase)\n\n**Reference (IdentyClaw) — wire format** (use your fresh values from Step 2):\n```javascript\n// Original message components (use YOUR fresh values)\nconst recipient = 'MUNDO';\nconst tokenId = 'bkbvehbdcrgm';  // Your 12-letter passport ID (lowercase from storage);\nconst timestamp = '2026-04-19T10:47:00.000Z';  // From Step 2 nonce response;\nconst noncetsHex = '4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE';  // From Step 2 nonce response;\n// Build message\nconst message = `HOLA/${recipient}/${tokenId}/${timestamp}/${noncetsHex}/API.IDENTYCLAW.COM/`;\n// Canonicalize: UPPERCASE EVERYTHING\nconst canonicalMessage = message.toUpperCase();\n// Result: \"HOLA/MUNDO/BKBVEHBDCRGM/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/\"\n// Sign the canonical message\nconst messageBytes = new TextEncoder().encode(canonicalMessage);\nconst signature = nacl.sign.detached(messageBytes, secretKey);\n```\n\n⚠️ **Critical**: Sign the **canonicalized (uppercase) message**, not the original case.\n\n## Step 3.6: Sign the Canonical Message\n\n**Signing:** Ed25519 detached over UTF-8 bytes of the **HOLA canonical prefix**; encode the result as **base32** for the HOLA line (not base64url).\n\n1. Convert **canonical (uppercase)** prefix to UTF-8 bytes\n2. Sign with Ed25519 secret key\n3. Encode signature as **base32** (RFC 4648, A-Z2-7, uppercase, no padding)\n\n**Reference (IdentyClaw) — JavaScript wire format** (use your fresh values):\n```javascript\nconst nacl = require('tweetnacl');\nconst base32 = require('hi-base32');\nconst bs58 = require('bs58');\nconst fs = require('fs');\n// 1. Load credentials\nconst creds = JSON.parse(fs.readFileSync('~/.near-credentials/mainnet/your-account.json'));\nconst privateKeyBase58 = creds.private_key.replace('ed25519:', '');\n// 2. Decode keypair\nconst keypair = bs58.decode(privateKeyBase58);\nconst secretKey = keypair.slice(0, 32);\n// 3. Build and canonicalize message (use YOUR fresh timestamp and nonce from Step 2)\nconst message = `HOLA/MUNDO/bkbvehbdcrgm/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/`;\nconst canonicalMessage = message.toUpperCase();\n// 4. Sign the canonical message\nconst messageBytes = new TextEncoder().encode(canonicalMessage);\nconst signature = nacl.sign.detached(messageBytes, secretKey);\n// 5. Encode as base32 (RFC 4648: A-Z2-7, uppercase, no padding)\nconst signatureB32 = base32.encode(Buffer.from(signature)).replace(/=+$/, '').toUpperCase();\n// Example result: \"MFRGG2LTMVZXGZLSN5XWC3TBNRQW4ZDJMQFA...\" (yours will differ)\n```\n\n**Reference (IdentyClaw) — Python wire format** (use your fresh values):\n```python\nfrom nacl.signing import SigningKey\nimport base58\nimport json\nimport base64\n# 1. Load credentials\ncreds = json.load(f)\nprivate_key_base58 = creds['private_key'].replace('ed25519:', '')\n# 2. Decode keypair\nkeypair = base58.b58decode(private_key_base58)\nsecret_key = keypair[:32]\n# 3. Build and canonicalize message (use YOUR fresh timestamp and nonce from Step 2)\nmessage = 'HOLA/MUNDO/bkbvehbdcrgm/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/'\ncanonical_message = message.upper()\n# 4. Sign the canonical message\nsigning_key = SigningKey(secret_key)\nsignature = signing_key.sign(canonical_message.encode('utf-8')).signature\n# 5. Encode as base32 (RFC 4648)\nimport base64\nsignature_b32 = base64.b32encode(signature).decode('utf-8').rstrip('=').upper()\n# Example result: \"MFRGG2LTMVZXGZLSN5XWC3TBNRQW4ZDJMQFA...\" (yours will differ)\n```\n\n## Step 3.7: Checksum Calculation\n\n**Alphabet (fixed order, length 23):** `ABCDEFGHJKMNPQRSTUVWXYZ` (uppercase Latin letters **without** **I**, **L**, **O**).\n\n**Algorithm**: Let `checksumPrefix` be the canonical uppercase signed payload through `API.IDENTYCLAW.COM/`, plus the base32 signature, plus a trailing `/`. Sum **UTF-16 code units** (same as JavaScript `charCodeAt` over that string—ASCII-only HOLA components match byte sums). Then `checksum = alphabet[sum % 23]`.\n\nThe checksum is calculated on the **canonicalized (uppercase) message + signature + trailing slash**.\n\n### Canonical string (signing and checksum)\n\nUse **one** uppercase prefix for both Ed25519 signing and the checksum (the signature is appended only for the checksum step):\n\n1. Build the signed prefix (field order and slashes matter):\n\n```\nHOLA/<recipient>/<tokenId>/<ISO-8601-timestamp>/<noncets-hex>/API.IDENTYCLAW.COM/\n```\n\n| Field | Meaning |\n|-------|---------|\n| `recipient` | Intended recipient (often `MUNDO`; may be another agent's 12-letter Passport ID when addressing them directly) |\n| `tokenId` | **Sender's** Passport id (12 letters; often stored lowercase, uppercased in canonical form) |\n| `noncets-hex` | 32 hex characters from `GET /api/holanonce16ts` (16 random bytes as hex — not 16 hex chars) |\n\n2. **Canonicalize:** `canonicalMessage = message.toUpperCase()` on the **entire** prefix string.\n3. **Sign:** Ed25519 detached signature over UTF-8 bytes of `canonicalMessage`.\n4. **Encode:** RFC 4648 base32, uppercase `A–Z2–7`, no `=` padding → `signatureB32` (always **103 characters** for Ed25519).\n5. **Checksum input:** `checksumPrefix = canonicalMessage + signatureB32 + \"/\"` — include the trailing `/`; do **not** include the checksum letter.\n\n**Self-test:** After assembling your HOLA, call `POST /api/testhola` while building as the sender. When validating a peer's HOLA, use `POST /api/identity/verify`. A checksum mismatch returns `expected` vs `got` in the error message — use that to diff your `checksumPrefix`.\n\n```javascript\n// Step 1: Build canonical message (already uppercase)\nconst canonicalMessage = message.toUpperCase();\n// Example: \"HOLA/MUNDO/BKBVEHBDCRGM/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/\"\n// Step 2: Add signature and trailing slash\nconst checksumPrefix = `${canonicalMessage}${signatureB32}/`;\n// Example: \"HOLA/MUNDO/.../API.IDENTYCLAW.COM/MFRGG2LTMVZXGZLSN5XWC3TBNRQW4ZDJMQFA.../\"\n// Step 3: Sum UTF-16 code units (charCodeAt)\nconst sum = 0;\nsum += checksumPrefix.charCodeAt(i);\n// Example: sum = 12543\n// Step 4: Modulo 23 and pick letter from fixed alphabet\nconst holaChecksumAlphabet = 'ABCDEFGHJKMNPQRSTUVWXYZ';\nconst checksum = holaChecksumAlphabet[sum % 23];\n// Example: 12543 % 23 = 8 → alphabet[8] = 'J'\n```\n\n**Full checksum input example** (one continuous line; signature is illustrative — yours will differ):\n\n```\nHOLA/MUNDO/BKBVEHBDCRGM/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/FCHWM6BHKU43A4GB2HO4J455TH3AHAV4WCJJOWBS3VLWSZDRFKR6PYCV7RTPLYABEUY75BOQ4ONOOJ3N4U5JAHB2YECVNDMISI3DUDI/\n```\n\nSum of UTF-16 code units over that string: 13807 → `13807 % 23 = 7` → checksum **`H`** (index 7 in `ABCDEFGHJKMNPQRSTUVWXYZ`).\n\n**Critical Notes**:\n- Checksum is calculated on the **uppercase canonical message**\n- Include the **trailing slash** after the signature: `\"...SIGNATURE/\"`\n- Use `charCodeAt()` (JavaScript) or equivalent UTF-16 code units over `checksumPrefix`\n- Result is always **one uppercase letter** from `ABCDEFGHJKMNPQRSTUVWXYZ`\n- This is **NOT** a cryptographic hash (it's a simple integrity check)\n\n**Final HOLA Pattern** (same values as the checksum example above; signature is illustrative):\n\n```\nHOLA/MUNDO/BKBVEHBDCRGM/2026-04-19T10:47:00.000Z/4F9A3C7E2D1B9A4CDEADBEEFCAFEBABE/API.IDENTYCLAW.COM/FCHWM6BHKU43A4GB2HO4J455TH3AHAV4WCJJOWBS3VLWSZDRFKR6PYCV7RTPLYABEUY75BOQ4ONOOJ3N4U5JAHB2YECVNDMISI3DUDI/H\n```\n\n## Complete Pattern Example\n\n**⚠️ Complete working code pattern - generate fresh values each time**\n\n### JavaScript Complete Implementation\n\n```javascript\nconst nacl = require('tweetnacl');\nconst base32 = require('hi-base32');\nconst bs58 = require('bs58');\nconst fs = require('fs');\nasync function generateHOLA(tokenId, jwtToken) {\n// 1. Get fresh nonce for this run\nconst nonceResponse = await fetch('https://api.identyclaw.com/api/holanonce16ts', {\n  headers: { 'Authorization': `Bearer ${jwtToken}` }\n});\n  throw new Error(`Failed to fetch nonce: ${nonceResponse.status}`)\nconst { noncetsHex, timestamp } = await nonceResponse.json();\n// Example: { noncetsHex: \"A1B2C3D4E5F6...\", timestamp: \"2026-05-04T10:09:00.000Z\" }\n// 2. Load your NEAR credentials\nconst creds = JSON.parse(fs.readFileSync(;\n`~/.near-credentials/mainnet/${tokenId}.near.json`;\n));\nconst privateKeyBase58 = creds.private_key.replace('ed25519:', '');\nconst keypair = bs58.decode(privateKeyBase58);\nconst secretKey = keypair.slice(0, 32);\n// 3. Build message\nconst recipient = 'MUNDO';\nconst message = `HOLA/${recipient}/${tokenId}/${timestamp}/${noncetsHex}/API.IDENTYCLAW.COM/`;\n// 4. Canonicalize (UPPERCASE)\nconst canonicalMessage = message.toUpperCase();\n// 5. Sign\nconst messageBytes = new TextEncoder().encode(canonicalMessage);\nconst signature = nacl.sign.detached(messageBytes, secretKey);\nconst signatureB32 = base32.encode(Buffer.from(signature)).replace(/=+$/, '').toUpperCase();\n// 6. Calculate checksum\nconst checksumPrefix = `${canonicalMessage}${signatureB32}/`;\nconst sum = 0;\nsum += checksumPrefix.charCodeAt(i);\nconst holaChecksumAlphabet = 'ABCDEFGHJKMNPQRSTUVWXYZ';\nconst checksum = holaChecksumAlphabet[sum % 23];\n// 7. Build final HOLA\nconst hola = `${canonicalMessage}${signatureB32}/${checksum}`;\nreturn {\n  hola,\n  tokenId,\n  recipient,\n  timestamp,\n  noncetsHex,\n  signatureB32,\n  checksum\n};\n// Usage:\n// const result = await generateHOLA('bjbvcjzqbdsj', yourJWT);\n// console.log('HOLA:', result.hola);\n```\n\n### Python Complete Implementation\n\n```python\nimport requests\nimport json\nfrom nacl.signing import SigningKey\nimport base58\nimport base64\n# 1. Get fresh nonce for this run\nnonce_response = requests.get(\nheaders = {'Authorization': f'Bearer {jwt_token}'}\n)\nnonce_data = nonce_response.json()\nnoncets_hex = nonce_data['noncetsHex']\ntimestamp = nonce_data['timestamp']\n# Example: { \"noncetsHex\": \"A1B2C3D4E5F6...\", \"timestamp\": \"2026-05-04T10:09:00.000Z\" }\n# 2. Load your NEAR credentials\ncreds = json.load(f)\nprivate_key_base58 = creds['private_key'].replace('ed25519:', '')\nkeypair = base58.b58decode(private_key_base58)\nsecret_key = keypair[:32]\n# 3. Build message\nrecipient = 'MUNDO'\nmessage = f'HOLA/{recipient}/{token_id}/{timestamp}/{noncets_hex}/API.IDENTYCLAW.COM/'\n# 4. Canonicalize (UPPERCASE)\ncanonical_message = message.upper()\n# 5. Sign\nsigning_key = SigningKey(secret_key)\nsignature = signing_key.sign(canonical_message.encode('utf-8')).signature\nsignature_b32 = base64.b32encode(signature).decode('utf-8').rstrip('=').upper()\n# 6. Calculate checksum\nchecksum_prefix = f'{canonical_message}{signature_b32}/'\nchar_sum = sum(ord(c) for c in checksum_prefix)\nhola_checksum_alphabet = 'ABCDEFGHJKMNPQRSTUVWXYZ'\nchecksum = hola_checksum_alphabet[char_sum % 23]\n# 7. Build final HOLA\nhola = f'{canonical_message}{signature_b32}/{checksum}'\n# Usage:\n# result = generate_hola('bjbvcjzqbdsj', your_jwt)\n# print('HOLA:', result['hola'])\n```\n\n**Key Points**:\n- ✓ Fetches **fresh nonce** from API (not hardcoded)\n- ✓ Uses **current timestamp** from nonce response\n- ✓ **Uppercases** entire message before signing\n- ✓ Returns complete HOLA ready to send\n- ✓ All values are **generated fresh** each time\n\n## Step 4: Send HOLA to Peer\n\nTransmit the HOLA message to the peer agent via your communication channel (HTTP, WebSocket, etc.).\n\nThe peer must apply **full validation** before treating your HOLA as authenticated — either directly (on-chain + local crypto) or via `POST /api/identity/verify` when using the IdentyClaw HTTP path ([When is a HOLA validated?](#when-is-a-hola-validated)).\n\n## Step 5: Verify HOLA (Peer Agent) — HTTP API path\n\nThis section documents **`POST /api/identity/verify`**, IdentyClaw's convenience implementation of full HOLA validation. If you verify peer-to-peer without the API, you must still apply the same substantive checks ([When is a HOLA validated?](#when-is-a-hola-validated)).\n\nWhen using this endpoint: if you only parse the string, recompute the checksum, or verify the Ed25519 signature locally without completing the full proof bar, you have **not** finished validation. **Treat a received HOLA as unvalidated un\n\nArchive v1.9.5: 19 files, 98570 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17899b), references/collaboration-envelope.md (8033b), references/did-rodit-method.md (27764b), references/enrollment.md (32233b), references/finding-agents.md (7067b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2855b), references/login-authentication.md (32323b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8800b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18898b), skill-card.md (2388b), SKILL.md (16751b), _meta.json (129b)\n\nArchive v1.9.4: 19 files, 98376 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17899b), references/collaboration-envelope.md (8033b), references/did-rodit-method.md (27764b), references/enrollment.md (32233b), references/finding-agents.md (7067b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2855b), references/login-authentication.md (32323b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8800b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18898b), skill-card.md (2119b), SKILL.md (16582b), _meta.json (129b)\n\nArchive v1.9.2: 19 files, 91909 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (8030b), references/did-rodit-method.md (9709b), references/enrollment.md (32246b), references/finding-agents.md (7071b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/login-authentication.md (32320b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8693b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18899b), skill-card.md (2724b), SKILL.md (16582b), _meta.json (129b)\n\nArchive v1.9.1: 19 files, 91996 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (8030b), references/did-rodit-method.md (9686b), references/enrollment.md (32250b), references/finding-agents.md (7071b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/login-authentication.md (32320b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8693b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18899b), skill-card.md (3142b), SKILL.md (16582b), _meta.json (129b)\n\nArchive v1.9.0: 19 files, 91836 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (8030b), references/did-rodit-method.md (9686b), references/enrollment.md (32250b), references/finding-agents.md (7071b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/login-authentication.md (32320b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8693b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18899b), skill-card.md (3113b), SKILL.md (16078b), _meta.json (129b)\n\nArchive v1.8.4: 19 files, 91292 bytes\n\nFiles: README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (8030b), references/did-rodit-method.md (9491b), references/enrollment.md (32101b), references/finding-agents.md (7061b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25515b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/login-authentication.md (32308b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8693b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18404b), skill-card.md (2980b), SKILL.md (15732b), _meta.json (129b)\n\nArchive v1.8.3: 23 files, 96260 bytes\n\nFiles: PUBLISH.md (755b), README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (7909b), references/did-rodit-method.md (9491b), references/enrollment.md (30986b), references/finding-agents.md (7061b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25407b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/inter-agent-communication.md (7918b), references/login-authentication.md (32044b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8608b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18054b), scripts/publish-clawhub.mjs (2170b), scripts/sync-references.mjs (1997b), skill-card.md (3190b), SKILL.md (15346b), _meta.json (129b)\n\nArchive v1.8.2: 23 files, 96278 bytes\n\nFiles: PUBLISH.md (755b), README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (7909b), references/did-rodit-method.md (9491b), references/enrollment.md (30986b), references/finding-agents.md (7061b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25407b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/inter-agent-communication.md (7918b), references/login-authentication.md (32044b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8608b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18054b), scripts/publish-clawhub.mjs (2170b), scripts/sync-references.mjs (1997b), skill-card.md (3404b), SKILL.md (15097b), _meta.json (129b)\n\nArchive v1.8.1: 23 files, 96105 bytes\n\nFiles: PUBLISH.md (755b), README.md (1035b), references/api-reference.md (17641b), references/collaboration-envelope.md (7909b), references/did-rodit-method.md (9491b), references/enrollment.md (30986b), references/finding-agents.md (7061b), references/hola-agent-authentication.md (38211b), references/hola-howto.md (5568b), references/hola-subagent-authentication.md (25407b), references/holanonce-api.md (1698b), references/identyclaw-skill.md (2827b), references/inter-agent-communication.md (7918b), references/login-authentication.md (32044b), references/mcp-auth-tools.md (4924b), references/mcp-discovery-index.md (8608b), references/openclaw-integration-guide.md (6795b), references/token-metadata.md (18054b), scripts/publish-clawhub.mjs (2170b), scripts/sync-references.mjs (1997b), skill-card.md (2928b), SKILL.md (15097b), _meta.json (129b)","readmeExcerpt":"Skill: IdentyClaw Owner: identyclaw Summary: IdentyClaw API workflows — multi-API JWT sessions (auto-login), HOLA peer handshake lines, DID resolution, and Passport lookup. Requires an IdentyClaw Passport on the Gateway. Use when calling home or federated APIs, creating or verifying HOLA lines, resolving Passport IDs, or reading agent discovery metadata. For agent-to-agent A2A messaging use the separate identyclaw-a2","codeSnippets":[],"executableExamples":[{"language":"json5","snippet":"{\n  plugins: {\n    entries: {\n      \"identyclaw-tools\": {\n        enabled: true,\n        config: {\n          baseUrl: \"https://api.identyclaw.com\",\n          apiEndpoints: [\"https://api-b.example.com\"],\n          accountid: \"<64-char-hex-near-implicit-account>\",\n          nearPrivateKey: \"ed25519:...\"\n        }\n      }\n    }\n  }\n}"},{"language":"text","snippet":"Skill (workflows):     openclaw skills install clawhub:identyclaw\nPlugin (API + HOLA):   openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\nPlugin (A2A P2P):      openclaw plugins install clawhub:@identyclaw/openclaw-a2a-plugin\nMCP (docs):            https://api.identyclaw.com/mcp\nDiscovery index:       doc:discovery\nCheat sheet:           doc:skills"},{"language":"text","snippet":"# Home identity / HOLA / DID\nidentyclaw_ensure_session\nidentyclaw_get_my_identity\nidentyclaw_list_sessions\n\n# Federated peer — login + discover + product routes (arbitrary paths)\nidentyclaw_ensure_session   apiEndpoint=https://api-b.example.com\nidentyclaw_list_resources   apiEndpoint=https://api-b.example.com\nidentyclaw_get_resource     uri=doc:discovery  apiEndpoint=https://api-b.example.com\nidentyclaw_request          method=GET path=/…  apiEndpoint=https://api-b.example.com"},{"language":"bash","snippet":"BASE=https://api.identyclaw.com   # or federated peer URL\n\nTS_JSON=$(curl -sS \"$BASE/api/login/timestamp\")\nTIMESTAMP=$(echo \"$TS_JSON\" | jq -r '.timestamp')\nTIMESTAMP_ISO=$(echo \"$TS_JSON\" | jq -r '.timestamp_iso')\n\n# Sign UTF-8: <accountid> + <timestamp_iso> (no separator) → base64url_signature\n\nJWT=$(curl -sS -X POST \"$BASE/api/login\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"{\\\"accountid\\\":\\\"<64-char-hex>\\\",\\\"timestamp\\\":$TIMESTAMP,\\\"base64url_signature\\\":\\\"<sig>\\\"}\" \\\n  | jq -r '.jwt_token')"},{"language":"text","snippet":"HOLA/<recipient>/<tokenId>/<timestamp>/<noncetsHex>/API.IDENTYCLAW.COM/<base32-signature>/<checksum>"},{"language":"bash","snippet":"openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: identyclaw\ndescription: >-\n  IdentyClaw API workflows — multi-API JWT sessions (auto-login), HOLA peer\n  handshake lines, DID resolution, and Passport lookup. Requires an IdentyClaw\n  Passport on the Gateway. Use when calling home or federated APIs, creating or\n  verifying HOLA lines, resolving Passport IDs, or reading agent discovery\n  metadata. For agent-to-agent A2A messaging use the separate identyclaw-a2a plugin.\nversion: 1.9.6\nmetadata:\n  openclaw:\n    envVars:\n      - name: IDENTYCLAW_BASE_URL\n        required: false\n        description: Home API base URL (default https://api.identyclaw.com)\n      - name: IDENTYCLAW_API_ENDPOINTS\n        required: false\n        description: Comma-separated federated API URLs for concurrent sessions (e.g. https://api-b.example.com)\n      - name: IDENTYCLAW_ACCOUNT_ID\n        required: false\n        description: NEAR implicit account id (64-char hex) for API login\n      - name: IDENTYCLAW_NEAR_PRIVATE_KEY\n        required: false\n        description: Passport Ed25519 key (ed25519:...) — API login signature + HOLA line signing (Gateway only)\n    homepage: https://api.identyclaw.com/docs\n---\n\n# IdentyClaw\n\n**Home API (default):** `https://api.identyclaw.com`  \n**Federated example:** `https://api-b.example.com` (same Rodit login family; configure via `apiEndpoints`)\n\nIdentyClaw is an HTTP API for IdentyClaw Passport holders and the **HOLA** mutual authentication protocol. This skill is a **convenience cheat sheet** for agents; tool catalog and install steps live in the plugin [README](https://github.com/discernible-io/openclaw-identyclaw-plugin/blob/main/README.md). Deep specs live in bundled `references/` and MCP `doc:*` resources.\n\n> **Convenience document:** Change the plugin README and MCP `doc:*` resources first; update this skill only to keep the walkthrough accurate.\n\n**Live docs:** MCP `doc:discovery` · `doc:skills` · `curl https://api.identyclaw.com/api/mcp/resource/doc:skills`\n\n**ClawHub:** [identyclaw/identyclaw](https://clawhub.ai/identyclaw/identyclaw) · [OpenClaw plugin](https://clawhub.ai/plugins/@identyclaw/openclaw-identyclaw-plugin) · [Source (skill + plugin)](https://github.com/discernible-io/openclaw-identyclaw-plugin)\n\n---\n\n## Home vs federated — do not assume shared routes\n\nFederation shares **Rodit login** only (`GET /api/login/timestamp` → sign → `POST /api/login` → JWT cached per URL). A federated peer may expose **any** product routes. It does **not** inherit the home IdentyClaw surface (`/api/me/identity`, HOLA, DID, `/api/agents`, …).\n\n| Target | What to call |\n| --- | --- |\n| **Home** (`baseUrl`, omit `apiEndpoint`) | Passport/HOLA/DID tools: `identyclaw_get_my_identity`, `identyclaw_create_hola`, `identyclaw_verify_hola`, `identyclaw_get_agent_identity`, `identyclaw_resolve_did`, … |\n| **Federated peer** (`apiEndpoint=…`) | `identyclaw_ensure_session` → **discover** (`identyclaw_list_resources` / `identyclaw_get_resource` / peer skill.md / OpenAPI) → **product calls** via "},{"path":"README.md","content":"# IdentyClaw ClawHub skill\n\nWorkflow skill for OpenClaw agents. Published separately from the code plugin on ClawHub (`clawhub:identyclaw`).\n\n## Layout\n\n```text\nskill/\n├── SKILL.md              # ClawHub publish source (version in frontmatter)\n├── references/           # gitignored — populated by skill:sync\n└── scripts/\n    ├── sync-references.mjs\n    └── publish-clawhub.mjs\n```\n\nReference docs are copied from **idclawserver-idc** at publish time (canonical API specs). Default path: `../idclawserver-idc/references`.\n\n## Development\n\nFrom repository root:\n\n```bash\nnpm run skill:sync\nnpm run skill:publish:dry-run\nnpm run skill:publish\n```\n\nOverride references source:\n\n```bash\nIDENTYCLAW_REFERENCES=/path/to/idclawserver-idc/references npm run skill:sync\n```\n\n## ClawHub\n\n- Skill: `openclaw skills install clawhub:identyclaw`\n- Plugin: `openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin`\n\nSee [PUBLISH.md](./PUBLISH.md) and root [PUBLISH.md](../PUBLISH.md) for ClawHub auth."},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7ev9fw0fs1g0z9r4wt5bg5bh86bmj7\",\n  \"slug\": \"identyclaw\",\n  \"version\": \"1.9.6\",\n  \"publishedAt\": 1791308517689\n}"},{"path":"references/api-reference.md","content":"# API Reference\n\nComplete endpoint listing for IdentyClaw API.\n\n## Table of Contents\n\n- [Public Endpoints](#public-endpoints)\n- [Protected Endpoints](#protected-endpoints)\n- [Privileged Endpoints](#privileged-endpoints)\n- [DID Resolution](#did-resolution)\n- [MCP Resources](#mcp-resources)\n- [Policy Documents](#policy-documents)\n\n## Public Endpoints\n\nNo authentication required.\n\n### Discovery\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/` | GET | API overview with enrollment URL and endpoint listing |\n| `/health` | GET | Health check endpoint |\n| `/.well-known/enrollment` | GET | Complete enrollment guide with pricing and steps |\n| `/.well-known/mcp` | GET | MCP discovery metadata — see [mcp-connection-guide.md](mcp-connection-guide.md) |\n| `/openapi.json` | GET | Canonical OpenAPI 3.0 specification |\n| `/swagger.json` | GET | OpenAPI 3.0 specification (alias of `/openapi.json`) |\n| `/api/v1/openapi.json` | GET | Deprecated redirect to `/openapi.json` |\n| `/docs/enrollment` | GET | **Removed** — always returns `410 ENDPOINT_REMOVED` |\n| `/api-docs` | * | **Removed** — always returns `410 ENDPOINT_REMOVED` |\n\n### Authentication\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/login/timestamp` | GET | Get single-use timestamp challenge pair for login |\n| `/api/login` | POST | Authenticate with accountid signature and fresh challenge, get JWT |\n\nLogin request/response shapes, field constraints, and error semantics are maintained in OpenAPI:\n\n- Canonical contract: [`../api-docs/swagger.json`](../../api-docs/swagger.json)\n- Runtime endpoints: `GET /openapi.json`, `GET /swagger.json`\n\nFor step-by-step API login implementation guidance (challenge retrieval, signing flow, retries, and troubleshooting), use:\n\n- [`login-authentication.md`](login-authentication.md)\n\n### Agent Discovery\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/agents` | GET | List all IdentyClaw Passport holders (cursor-paginated) |\n\n**Query Parameters**:\n- `limit` (default: 20, max: 100)\n- `cursor` (optional, for pagination)\n\n**Response**:\n```json\n{\n  \"agents\": [\n    {\n      \"tokenId\": \"bkbvehbdcrgm\",\n      \"creature\": \"Legal Specialist\",\n      \"face\": {\n        \"checksumValid\": true,\n        \"categories\": {\n          \"skinTone\": { \"index\": 2, \"letter\": \"c\", \"value\": \"pale-skinned\" },\n          \"ethnicity\": { \"index\": 1, \"letter\": \"b\", \"value\": \"Nordic\" },\n          \"faceShape\": { \"index\": 0, \"letter\": \"a\", \"value\": \"oval-faced\" }\n        }\n      }\n    }\n  ],\n  \"nextCursor\": \"cursor_string_or_null\",\n  \"requestId\": \"01HQXYZ...\",\n  \"disclaimer\": \"The creature field and other agent metadata are self-declared by the agent. It is your responsibility to verify the accuracy and authenticity of this information before relying on it.\"\n}\n```\n\n### Client Token Signing\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/api/signclient` | POST | Request server to sign client to"},{"path":"references/collaboration-envelope.md","content":"# Channel-Agnostic Collaboration Envelope\n\n**Schema:** `identyclaw.collaboration.v1`  \n**MCP resource URI:** `doc:reference:collaboration-envelope`\n\nIdentyClaw provides **identity and trust**, not transport. Email, chat, webhooks, game private side-channels, and paste-in-message channels each need a shared envelope so agents can attach cryptographic trust (HOLA), carry a task payload, and verify inbound messages uniformly.\n\n**HOLA travels offline, peer-to-peer.** Agents exchange envelopes and HOLA lines **directly** on the channel they already use. Each peer **verifies independently** (IdentyClaw API or direct NEAR RPC — peer's choice). Do not route HOLA **exchange** through IdentyClaw HTTP API or a game server — those are separate services, not brokers for the wire path.\n\n**Related:** MCP `doc:reference:inter-agent-communication` (optional email/Himalaya patterns — **out of scope** for the ClawHub `identyclaw` skill; A2A uses the separate plugin), [`multi-tenant-collaboration.md`](multi-tenant-collaboration.md) (operator patterns), [`identity-verification-policy.md`](identity-verification-policy.md) (proof bar), `doc:reference:hola-subagent-authentication`, `doc:reference:openclaw-integration-guide`.\n\n---\n\n## Envelope shape\n\n```json\n{\n  \"schema\": \"identyclaw.collaboration.v1\",\n  \"messageId\": \"01HXABCDEFGHJKMNPQRSTVWXYZ0\",\n  \"timestamp\": \"2026-06-06T12:00:00.000Z\",\n  \"from\": { \"tokenId\": \"bkbvehbdcrgm\" },\n  \"to\": { \"tokenId\": \"lncnsfsnskzr\", \"contactUri\": \"mailto:agent@example.com\" },\n  \"hola\": \"HOLA/MUNDO/bkbvehbdcrgm/2026-06-06T12:00:00.000Z/4F9A3C7E2D1B9A4C/API.IDENTYCLAW.COM/MFRGG.../J\",\n  \"task\": {\n    \"type\": \"TASK_REQUEST\",\n    \"payload\": {\n      \"summary\": \"Run benchmark X and return JSON metrics\"\n    }\n  },\n  \"channelHints\": {\n    \"replyVia\": \"contactUri\",\n    \"subjectPrefix\": \"TASK_RESULT:\"\n  }\n}\n```\n\n| Field | Required | Notes |\n| --- | --- | --- |\n| `schema` | yes | Must be `identyclaw.collaboration.v1` |\n| `messageId` | yes | ULID or UUID — dedupe on receiver |\n| `timestamp` | yes | ISO 8601 UTC — reject stale envelopes beyond HOLA TTL |\n| `from.tokenId` | yes | Sender Passport ID (12 lowercase letters) |\n| `to.tokenId` | no | Intended recipient Passport ID |\n| `to.contactUri` | no | Routing hint from sender's view (`mailto:`, `https://`, etc.) |\n| `hola` | yes* | Full HOLA line from sender (*omit only in trusted internal channels with separate verify) |\n| `task` | yes | `{ type, payload }` — channel-independent work description |\n| `channelHints` | no | Reply routing (`subjectPrefix`, `replyVia`) |\n\n**Subagent delegation:** When `hola` uses the subagent format, also run `POST /api/isauthorizedsigner` after verify succeeds — see `doc:reference:hola-subagent-authentication`.\n\n---\n\n## Verification order (receiver)\n\n**Verify before execute** — the norm for every channel. Copy-paste verifier recipes: [`verify-hola-recipes.md`](verify-hola-recipes.md) (MCP `doc:reference:verify-hola-recipes`).\n\n1. **Parse** — valid JSON, `schema === ident"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1801,"uniquenessScore":44,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T23:05:35.518Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T05:39:00.870Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}