{"type":"text/markdown","content":"---\nname: IdentyClaw\ndescription: Practical IdentyClaw API guide for agents — API session login (JWT), HOLA peer handshake lines, verify (`POST /api/identity/verify`), nonce fetch, and identity lookup. Use when verifying peer agents, proving your identity, resolving Passport IDs, or reading `face.categories` (see `references/token-metadata.md`).\n---\n\n# IdentyClaw Agent Skills\n\n**Base URL:** `https://api.identyclaw.com`\n\nIdentyClaw is an HTTP API for IdentyClaw Passport holders and the **HOLA** mutual authentication protocol. Deep protocol detail lives in linked references; this doc is the **runnable cheat sheet**.\n\n**Fetch via MCP:** `doc:discovery` (index) · `doc:skills` (cheat sheet) · `curl https://api.identyclaw.com/api/mcp/resource/doc:skills`\n\n**ClawHub skill source:** `identyclaw-skill/SKILL.md` (synced with this doc at publish). **Plugin source:** [github.com/discernible-io/openclaw-identyclaw-plugin](https://github.com/discernible-io/openclaw-identyclaw-plugin).\n\n**Other runtimes:** Hermes, IronClaw, NanoClaw, and Cursor — see MCP `doc:reference:agent-frameworks` or [`agent-frameworks.md`](agent-frameworks.md).\n\n---\n\n## Two lanes — do not mix them\n\n| Lane | Artifact | Typical TTL | Docs |\n| --- | --- | --- | --- |\n| **API login** | Bearer JWT (`jwt_token`) | ~1 hour | [login-authentication.md](login-authentication.md) |\n| **HOLA protocol** | HOLA line (wire string) | ~5 min (nonce) | [hola-howto.md](hola-howto.md), [hola-agent-authentication.md](hola-agent-authentication.md) |\n\n| Endpoint | Fields | Purpose |\n| --- | --- | --- |\n| `GET /api/login/timestamp` | `timestamp`, `timestamp_iso` | API login signing |\n| `GET /api/holanonce16ts` | `noncetsHex`, `timestamp` | HOLA line construction — [holanonce-api.md](holanonce-api.md) |\n\nA JWT is **not** a HOLA line. Protected HOLA endpoints need an API session; the handshake payload is the HOLA string.\n\n---\n\n## Install and entry points\n\n```text\nSkill (workflows):     openclaw skills install clawhub:identyclaw\n                       https://clawhub.ai/identyclaw/identyclaw\nPlugin (tools):        openclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\n                       https://clawhub.ai/plugins/@identyclaw/openclaw-identyclaw-plugin\nMCP (docs):            https://api.identyclaw.com/mcp\nDiscovery index:       doc:discovery\nCheat sheet:           doc:skills\n```\n\nFull discovery map: MCP resource `doc:discovery` or [`mcp-discovery-index.md`](mcp-discovery-index.md).\n\n**Verifiers (integrators):** **Verify before execute** — peer HOLA is **offline P2P** between agents; each peer verifies **independently** (IdentyClaw API or direct NEAR RPC, peer's choice). Recipes: [`verify-hola-recipes.md`](verify-hola-recipes.md) (MCP `doc:reference:verify-hola-recipes`). Publish your canonical `tokenId` on channels you control.\n\n---\n\n## Agent cheat sheet\n\nProtected routes need `Authorization: Bearer <jwt_token>` from `POST /api/login`. **`POST /api/identity/verify` is public** — no JWT required (nginx edge rate limit); an optional bearer enables `RECIPIENT_MISMATCH` warnings (suppress with `expectedRecipient`). Field name is **`jwt_token`**. JWT lasts ~1 hour; HOLA nonces last ~5 minutes — fetch a **new** nonce immediately before each HOLA you sign.\n\n| # | Goal | Method | Lane |\n|---|------|--------|------|\n| 1 | API session (JWT) | `GET /api/login/timestamp` → sign → `POST /api/login` | API login |\n| 2 | **Create outbound HOLA line** | `identyclaw_create_hola` or `@rodit/hola-client` | HOLA (+ API session) |\n| 3 | **Verify peer HOLA line** | `POST /api/identity/verify` | HOLA (public; optional JWT) |\n| 4 | Resolve Passport → full DN | `GET /api/identity/token/{tokenId}/full` | API session |\n| 5 | List public agents | `GET /api/agents?limit=20` | Public |\n| 6 | Resolve DID | `GET /.well-known/did/resolve?did=did:rodit:{tokenId}` | API session |\n\n### 1. Login (get JWT)\n\n**curl**\n\n```bash\nBASE=https://api.identyclaw.com\n\n# One-time challenge — use both fields from the same response, once\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 bytes of: <accountid> + <timestamp_iso> (no separator)\n# → base64url_signature with your NEAR/Passport Ed25519 key (see login-authentication.md)\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\ncurl -sS \"$BASE/api/me/identity\" -H \"Authorization: Bearer $JWT\"\n```\n\n**Node** (requires `accountid` + NEAR private key in env; uses `tweetnacl` + `bs58` like the OpenClaw plugin)\n\n```javascript\nimport nacl from \"tweetnacl\";\nimport bs58 from \"bs58\";\n\nconst BASE = process.env.IDENTYCLAW_BASE_URL ?? \"https://api.identyclaw.com\";\nconst accountid = process.env.IDENTYCLAW_ACCOUNT_ID; // 64-char hex NEAR account\nconst nearPrivateKey = process.env.IDENTYCLAW_NEAR_PRIVATE_KEY; // ed25519:...\n\nfunction base64Url(bytes) {\n  return Buffer.from(bytes).toString(\"base64url\");\n}\n\nconst keyBody = nearPrivateKey.replace(/^ed25519:/, \"\").trim();\nconst secretKey = bs58.decode(keyBody).slice(0, 32);\n\nconst ts = await (await fetch(`${BASE}/api/login/timestamp`)).json();\nconst message = `${accountid}${ts.timestamp_iso}`;\nconst sig = nacl.sign.detached(new TextEncoder().encode(message), secretKey);\n\nconst login = await fetch(`${BASE}/api/login`, {\n  method: \"POST\",\n  headers: { \"content-type\": \"application/json\" },\n  body: JSON.stringify({\n    accountid,\n    timestamp: ts.timestamp,\n    base64url_signature: base64Url(sig),\n  }),\n}).then((r) => r.json());\n\nconst JWT = login.jwt_token; // ~1 hour; refresh when 401\n```\n\nFull signing steps: [`references/login-authentication.md`](login-authentication.md#quick-start-login-pattern). JWT storage pitfalls: [`references/mcp-auth-tools.md`](mcp-auth-tools.md).\n\n---\n\n### 2. Create outbound HOLA\n\n**Recommended:** OpenClaw **`identyclaw_create_hola`** (plugin v1.4.0+) or **`@rodit/hola-client`** `createHola()` — API session fetches nonce; **HOLA line signed locally** (`nearPrivateKey` never sent to HTTP except inside the finished HOLA string).\n\n```bash\n# OpenClaw Gateway — allowlist identyclaw_create_hola; configure nearPrivateKey in plugin config\n# Returns: { hola, noncetsHex, timestamp, tokenId, recipient, ... }\n```\n\n```javascript\nconst { createHola } = require(\"@rodit/hola-client\");\n\nconst { hola } = await createHola({\n  baseUrl: \"https://api.identyclaw.com\",\n  jwt: JWT,\n  nearPrivateKey: process.env.IDENTYCLAW_NEAR_PRIVATE_KEY,\n  tokenId: \"yourpassportid\", // or omit when using identyclaw_create_hola (from /api/me/identity)\n  recipient: \"MUNDO\",\n});\n```\n\n**Manual path** — use **`noncetsHex`** and **`timestamp`** from `GET /api/holanonce16ts` (not login `timestamp_iso`). Standard line:\n\n```text\nHOLA/<recipient>/<tokenId>/<timestamp>/<noncetsHex>/API.IDENTYCLAW.COM/<base32-signature>/<checksum>\n```\n\n**curl — fetch nonce**\n\n```bash\ncurl -sS https://api.identyclaw.com/api/holanonce16ts \\\n  -H \"Authorization: Bearer $JWT\"\n# → { \"noncetsHex\", \"timestamp\", \"length\", \"algorithm\", \"requestId\" }\n```\n\nSelf-test your line before sending to peers:\n\n```bash\ncurl -sS -X POST https://api.identyclaw.com/api/testhola \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"hola\":\"<your line>\"}'\n```\n\nBuild/sign walkthrough: [`references/hola-howto.md`](hola-howto.md). Full spec: [`references/hola-agent-authentication.md`](hola-agent-authentication.md).\n\n---\n\n### 3. Verify an incoming HOLA (most important)\n\n**One call validates format, checksum, freshness, nonce replay, token existence/active, and on-chain signature.** No Passport or JWT is required; pin the API hostname (see [finding-agents.md](finding-agents.md#6-verify-the-api-server-mitm-protection)).\n\n```bash\ncurl -sS -X POST https://api.identyclaw.com/api/identity/verify \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"hola\":\"HOLA/MUNDO/<peerTokenId>/2026-06-03T12:00:00.000Z/<noncetsHex>/API.IDENTYCLAW.COM/<sig>/<checksum>\",\"expectedRecipient\":\"MUNDO\"}'\n# Optional: -H \"Authorization: Bearer $JWT\" when logged in — enables RECIPIENT_MISMATCH unless expectedRecipient is set\n```\n\nOptional body fields on `POST /api/identity/verify`:\n\n- `expectedRecipient` — suppress `RECIPIENT_MISMATCH` when verifying a peer HOLA intentionally (e.g. `recipient=MUNDO` while logged in as yourself, or when sending optional JWT)\n- `constraints.maxAgeMs` — freshness window (default 300000 ms)\n\n`POST /api/testhola` accepts only `hola` and optional `expectedRecipient` (no `constraints`).\n\n**Node**\n\n```javascript\nconst headers = { \"content-type\": \"application/json\" };\n// if (JWT) headers.authorization = `Bearer ${JWT}`; // optional — RECIPIENT_MISMATCH when authenticated\n\nconst result = await fetch(\"https://api.identyclaw.com/api/identity/verify\", {\n  method: \"POST\",\n  headers,\n  body: JSON.stringify({\n    hola: peerHolaLine,\n    expectedRecipient: \"MUNDO\",\n  }),\n}).then((r) => r.json());\n\nif (result.verified) {\n  const peerTokenId = result.peerTokenId; // 12-letter Passport ID\n  // Best action next: send your own HOLA back immediately (cheat sheet §2) — do not wait for the user to ask\n  // then identity lookup + impersonation guard\n}\n```\n\nSee [Verify any HOLA in one call](#verify-any-hola-in-one-call) below for the response shape and failure codes.\n\n**Do not** trust a peer based on local checksum/signature alone — wait for `verified: true` from this endpoint (or equivalent direct on-chain verification).\n\n**After `verified: true` on an inbound peer HOLA:** reply with **your own** outbound HOLA on the **same channel** without waiting for a user prompt. Verifying them is only half of mutual authentication — they still need cryptographic proof of who you are.\n\n---\n\n### 4. Resolve tokenId → full identity\n\nAfter verify (or when you already trust a `tokenId` from a canonical channel):\n\n```bash\ncurl -sS \"https://api.identyclaw.com/api/identity/token/<tokenId>/full\" \\\n  -H \"Authorization: Bearer $JWT\"\n```\n\n**Node**\n\n```javascript\nconst tokenId = \"bkbvehbdcrgm\";\nconst identity = await fetch(\n  `https://api.identyclaw.com/api/identity/token/${tokenId}/full`,\n  { headers: { authorization: `Bearer ${JWT}` } }\n).then((r) => r.json());\n// DN, contactUri, face.categories, metadata.webhook_url (OpenClaw gateway base when set), disclaimer — self-declared; verify out-of-band\n```\n\nPublic browse (no JWT): `GET /api/agents?limit=20&cursor=...` — then use `/full` per candidate. Patterns: MCP `doc:reference:finding-agents` or [`finding-agents.md`](finding-agents.md).\n\n---\n\n### 5. Discover agents (public)\n\n```bash\ncurl -sS \"https://api.identyclaw.com/api/agents?limit=20\"\n```\n\n---\n\n## Verify any HOLA in one call\n\n**Verify before execute:** trust inbound work only after **independent HOLA validation** on the receiving peer (IdentyClaw API or direct RPC — peer's choice). Peer HOLA is not exchanged through a central broker. Integrator notes: [`verify-hola-recipes.md`](verify-hola-recipes.md) · MCP `doc:reference:verify-hola-recipes`.\n\n`POST /api/identity/verify` is IdentyClaw's packaged **peer verification** — the endpoint to reach for on first contact, email handoffs, MCP tool results, or any untrusted agent message carrying a HOLA line.\n\n**Request**\n\n```json\n{ \"hola\": \"HOLA/MUNDO/bkbvehbdcrgm/2026-06-03T12:00:00.000Z/4F9A3C7E.../API.IDENTYCLAW.COM/MFRGG.../J\" }\n```\n\nOptional: `\"expectedRecipient\": \"MUNDO\"` suppresses the `RECIPIENT_MISMATCH` warning when you verify a peer's HOLA while logged in as yourself (common for `recipient=MUNDO` test lines).\n\n- `hola` must be a **single string**, not a nested JSON object (`reasonCode: payload_is_json_object` if wrong).\n- **Public endpoint** — no bearer token required (edge rate-limited). Optional JWT: caller's authenticated `tokenId` drives `RECIPIENT_MISMATCH` (suppress with `expectedRecipient`).\n\n**Success (HTTP 200, trust only when `verified` is true)**\n\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  \"failureDetails\": [],\n  \"signatureVerificationImplemented\": true,\n  \"requestId\": \"01HX...\"\n}\n```\n\n**Failure (still HTTP 200 for well-formed requests — read `verified` and `failureReasons`)**\n\n```json\n{\n  \"verified\": false,\n  \"peerTokenId\": \"bkbvehbdcrgm\",\n  \"checks\": {\n    \"timestampFresh\": false,\n    \"signatureValid\": false,\n    \"checksumValid\": true\n  },\n  \"failureReasons\": [\"timestamp_stale_or_future\", \"signature_invalid\"],\n  \"failureDetails\": [\n    { \"reasonCode\": \"timestamp_stale_or_future\", \"hint\": \"...\" },\n    { \"reasonCode\": \"signature_invalid\", \"hint\": \"...\" }\n  ]\n}\n```\n\nCommon `failureReasons`: `checksum_invalid`, `timestamp_stale_or_future`, `nonce_replay`, `token_missing`, `token_expired`, `signature_invalid`, `public_key_unavailable`, `public_key_error`.\n\nEarly malformed payloads return **HTTP 400** with `code: HOLA_VALIDATION_FAILED` (same family as `/api/testhola`). Full diagnostic tables: [`references/hola-agent-authentication.md`](hola-agent-authentication.md#verification-result-diagnostics-apidentityverify).\n\n**`/api/testhola` vs `/api/identity/verify`**\n\n| Endpoint | Use when |\n|----------|----------|\n| `POST /api/testhola` | Debugging **your own** HOLA before sending |\n| `POST /api/identity/verify` | Deciding whether to trust **another agent's** HOLA |\n\nSubagent HOLA also requires `POST /api/isauthorizedsigner` after verify succeeds — MCP `doc:reference:hola-subagent-authentication` or [`hola-subagent-authentication.md`](hola-subagent-authentication.md).\n\n---\n\n## First contact from an unknown agent\n\nCanonical flow when a stranger sends you a HOLA (chat, email, webhook, etc.):\n\n```mermaid\nsequenceDiagram\n  participant Unknown as Unknown agent\n  participant You as Your agent\n  participant API as api.identyclaw.com\n\n  Unknown->>You: HOLA line (out of band)\n  You->>API: POST /api/identity/verify {\"hola\":\"...\"}\n  API-->>You: verified, peerTokenId, checks, failureReasons\n  alt verified true\n    You->>API: GET /api/login/timestamp → POST /api/login\n    API-->>You: jwt_token\n    You->>API: identyclaw_create_hola (recipient=peerTokenId)\n    API-->>You: your HOLA line\n    You->>Unknown: Your HOLA (same channel — do not wait for user prompt)\n    You->>API: GET /api/identity/token/{peerTokenId}/full\n    API-->>You: DN, contactUri, metadata\n    You->>You: Impersonation guard (canonical ID vs HOLA tokenId)\n  else verified false\n    You->>You: Reject; do not grant tools/secrets\n  end\n```\n\n**Steps**\n\n1. **Verify** — `POST /api/identity/verify` with the exact HOLA string received (no JWT required). Do not skip this for \"quick\" local crypto checks.\n2. **If `verified: true` — login and reply with your HOLA immediately (best action).** Outbound HOLA and identity lookup need a JWT (cheat sheet §1). HOLA is **mutual** authentication: verifying the peer proves who they are; they still need proof of who you are. **Do not stop after verify** and wait for the user to say \"now send your HOLA\" — create and deliver your outbound line on the **same channel** (chat, email, webhook reply, etc.) as part of completing the handshake.\n   - Use `identyclaw_create_hola` or cheat sheet §2 (`@rodit/hola-client` / manual nonce + sign).\n   - Set `recipient` to the peer's `peerTokenId` when replying to a known peer; `MUNDO` is fine for broadcast first contact.\n   - HOLA nonces expire in ~5 minutes — reply promptly after verify succeeds.\n3. **Note `peerTokenId`** — 12-letter Passport ID from the verify response.\n4. **Lookup** — `GET /api/identity/token/{peerTokenId}/full` for DN/`contactUri`/`metadata.webhook_url`/traits (self-declared; JWT required).\n5. **Impersonation guard** — compare `peerTokenId` to the Passport ID published on channels the entity controls (website, verified social). If the verified `peerTokenId` is not the same ID the entity officially publishes, reject them as that entity, even though HOLA verification succeeded. See MCP `doc:reference:finding-agents` or [`finding-agents.md`](finding-agents.md#5-guard-against-impersonation).\n6. **Subagent only** — if the line includes delegation fields, also call `POST /api/isauthorizedsigner` (JWT required).\n\n**curl script (verify + lookup)**\n\n```bash\nBASE=https://api.identyclaw.com\nPEER_HOLA='HOLA/MUNDO/...'  # exact string from the unknown agent\n\nVERIFY=$(curl -sS -X POST \"$BASE/api/identity/verify\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$(jq -n --arg h \"$PEER_HOLA\" '{hola:$h}')\")\n\necho \"$VERIFY\" | jq .\nVERIFIED=$(echo \"$VERIFY\" | jq -r '.verified')\nTOKEN=$(echo \"$VERIFY\" | jq -r '.peerTokenId')\n\nif [ \"$VERIFIED\" = \"true\" ] && [ -n \"$TOKEN\" ] && [ \"$TOKEN\" != \"null\" ]; then\n  # Lookup requires JWT (cheat sheet §1)\n  curl -sS \"$BASE/api/identity/token/$TOKEN/full\" \\\n    -H \"Authorization: Bearer $JWT\" | jq .\nfi\n```\n\n---\n\n## Extended workflows (by reference)\n\n| Topic | Document | MCP resource |\n|-------|----------|--------------|\n| Agent frameworks | [`agent-frameworks.md`](agent-frameworks.md) | `doc:reference:agent-frameworks` |\n| Discovery index | [`mcp-discovery-index.md`](mcp-discovery-index.md) | `doc:discovery` |\n| ClawHub skill pointer | [`identyclaw-skill.md`](identyclaw-skill.md) | `doc:reference:identyclaw-skill` |\n| Find agents + impersonation guard | [`finding-agents.md`](finding-agents.md) | `doc:reference:finding-agents` |\n| Email + channel outreach | [`inter-agent-communication.md`](inter-agent-communication.md) | `doc:reference:inter-agent-communication` |\n| Collaboration envelope (normative) | [`collaboration-envelope.md`](collaboration-envelope.md) | `doc:reference:collaboration-envelope` |\n| OpenClaw webhooks | [`openclaw-integration-guide.md`](openclaw-integration-guide.md) | `doc:reference:openclaw-integration-guide` |\n| Verify before execute (verifier recipes) | [`verify-hola-recipes.md`](verify-hola-recipes.md) | `doc:reference:verify-hola-recipes` |\n| Linear HOLA path (login → verify) | [`hola-howto.md`](hola-howto.md) | `doc:reference:hola-howto` |\n| Enrollment + NEAR setup | [`enrollment.md`](enrollment.md) | `guide:enrollment`, `onboarding:near` |\n| Standard HOLA spec | [`hola-agent-authentication.md`](hola-agent-authentication.md) | `doc:reference:hola-authentication` |\n| Subagent delegation | [`hola-subagent-authentication.md`](hola-subagent-authentication.md) | `doc:reference:hola-subagent-authentication`, `guide:subagents` |\n| Nonce JSON shape | [`holanonce-api.md`](holanonce-api.md) | `doc:reference:holanonce-api` |\n| API login + MITM notes | [`login-authentication.md`](login-authentication.md) | `doc:reference:login-authentication`, `doc:reference:mcp-auth-tools` |\n| Endpoint catalog | [`api-reference.md`](api-reference.md) | `openapi:swagger` |\n| DID resolution | [`did-rodit-method.md`](did-rodit-method.md) | `doc:reference:did-rodit-method`, `did:resolve:{tokenId}` |\n| Key rotation | [`key-rotation.md`](key-rotation.md) | `guide:key-rotation` |\n| MCP setup | [`mcp-connection-guide.md`](mcp-connection-guide.md) | `doc:reference:mcp-connection-guide` |\n\n**HOLA formats**\n\nStandard:\n\n```text\nHOLA/<recipient>/<tokenId>/<timestamp>/<noncetsHex>/API.IDENTYCLAW.COM/<signature>/<checksum>\n```\n\nSubagent (delegation):\n\n```text\nHOLA/<recipient>/<delegateID>/<issuer_tokenId>/<publicKey>/<timestamp>/<noncetsHex>/API.IDENTYCLAW.COM/<signature>/<checksum>\n```\n\n**DID (JWT required)**\n\n```bash\ncurl -sS \"https://api.identyclaw.com/.well-known/did/resolve?did=did:rodit:<tokenId>\" \\\n  -H \"Authorization: Bearer $JWT\"\n```\n\n---\n\n## MCP quick connect\n\n```json\n{\n  \"mcpServers\": {\n    \"IdentyClaw\": {\n      \"url\": \"https://api.identyclaw.com/mcp\",\n      \"description\": \"IdentyClaw API documentation (MCP docs-only — use plugin or curl for authenticated calls)\"\n    }\n  }\n}\n```\n\nList/fetch docs without MCP client:\n\n```bash\ncurl https://api.identyclaw.com/api/mcp/resources\ncurl https://api.identyclaw.com/api/mcp/resource/doc:skills\n```\n\nTools: `list_resources`, `get_resource`. Client-side auth patterns: [`mcp-auth-tools.md`](mcp-auth-tools.md).\n\n**Interactive API:** OpenAPI at `GET https://api.identyclaw.com/openapi.json` (alias `GET /swagger.json`)\n\n---\n\n## OpenClaw agent tools (plugin)\n\nFor OpenClaw Gateways, prefer the published plugin over hand-rolled curl in every workspace:\n\n```bash\nopenclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\n```\n\n**Public:** `identyclaw_list_agents`, `identyclaw_list_resources`, `identyclaw_get_resource`.\n\n**API session:** `identyclaw_get_my_identity`, `identyclaw_get_agent_identity`, `identyclaw_check_subagent_signer`, `identyclaw_resolve_did`.\n\n**HOLA protocol:** `identyclaw_get_nonce`, `identyclaw_create_hola`, `identyclaw_verify_hola` (verify maps to a **public** endpoint; plugin may still send JWT for recipient checks).\n\n| Tool | Maps to |\n| --- | --- |\n| `identyclaw_create_hola` | HOLA line via `@rodit/hola-client` (API session + local sign) |\n| `identyclaw_verify_hola` | `POST /api/identity/verify` (peer HOLA line; JWT optional) |\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?did=did:rodit:{tokenId}` |\n\n`nearPrivateKey` on the Gateway: **API login** (base64url) and **HOLA create** (base32) — different messages. Configure under `plugins.entries.identyclaw-tools.config`. Plugin **v1.4.0+**; README: [openclaw-identyclaw-plugin](https://github.com/discernible-io/openclaw-identyclaw-plugin/blob/main/README.md).\n\n**ClawHub skill (workflows):** `openclaw skills install clawhub:identyclaw`\n\n---\n\n## Notes and conventions\n\n### Terminology\n\n| Term | Meaning | When to use |\n|------|---------|-------------|\n| **IdentyClaw Passport** | On-chain credential holders mint (12-letter Passport ID) | Enrollment, identity, user-facing copy |\n| **RODiT** | Underlying technology (token format, HOLA proofs, `did:rodit`, JSON-LD) | Protocol specs, SDK names, implementation only |\n| **IdentyClaw API** | Optional HTTP service for Passport holders | Login, nonces, discovery, verify helpers |\n\n**Do not say \"RODiT Passport.\"** Passports are IdentyClaw Passports; RODiT is the technology they use.\n\nPassport holders may use the API for convenience or verify peers directly on-chain without API involvement. See [`public/policies/why-identyclaw.md`](../public/policies/why-identyclaw.md) §3.1.\n\n### Two clocks\n\n| Clock | TTL | Source | Used for |\n|-------|-----|--------|----------|\n| **JWT session** | ~1 hour | `POST /api/login` | Bearer on protected routes |\n| **HOLA nonce** | ~5 minutes | `GET /api/holanonce16ts` | Timestamp + nonce inside each HOLA line |\n\n### Token ID and metadata\n\nFacial trait ranges: [`token-metadata.md`](token-metadata.md#facial-token-id-encoding). Decoded selections on your identity: `GET /api/me/identity` → `face.categories`.\n\n### Pricing (summary)\n\n- **Personal:** formula-based, min 0.066 NEAR / 30 days (48 req/min)\n- **Enterprise:** 148–1,806 NEAR/year (4,999 req/min)\n- **Collectible:** 496 NEAR one-time\n\nDetails: [`pricing-philosophy.md`](pricing-philosophy.md).\n\n### Policies\n\n`public/policies/` and `/.well-known/` — terms, privacy, data retention, why-identyclaw.\n","requestId":"5f1bc071530e495009456d51ee946bf9"}