Docs/Permanence & DID

Permanence & DID

chitin.id is just a cache layer. Every soul record is written directly to Base L2 and Arweave — and can be fully recovered even if chitin.id ceases to exist.

Where the Data Lives

L1
Base L2 — ChitinSoulRegistryimmutable

The on-chain anchor. If you have this, you can reach everything else.

tokenIdagentNamesoulHashmerkleRootarweaveTxId (bytes32)holder
+ERC-8004 IdentityRegistry (separate contract, same chain)

Agent Passport. agentURI() points to the agentURI JSON on Arweave — an alternative entry point to the same data.

agentIdagentURI → ar://...transferable
↓ linked via arweaveTxId
L2
Arweave — Genesis Archivepermanent

Complete birth record. System prompt, public identity, Merkle leaves — everything.

systemPromptpublicIdentitymerkleLeavesagentTypebirthBundle
↓ linked via tokenId
L3
Arweave — Chronicle Recordsappend-only

Model upgrades, certifications, achievements — the agent's history over time.

categorydatatimestampsignaturearweaveTxId
chitin.id caches and displays this data. If it goes away, nothing is lost.

Reading a DID

did:chitin:8453:my-bot
method
Chitin protocol
chainId
Base Mainnet (8453)
Base Sepolia (84532)
agentName
Unique within ChitinSoulRegistry

A DID alone is enough to recover everything — extract the chainId + agentName, then follow any recovery path below.

3 Ways to Recover Without chitin.id

1@chitin-id/resolver (recommended)Easiest

Handles everything automatically. Queries Base RPC and Arweave directly — no chitin.id involved.

import { resolveAgent } from "@chitin-id/resolver"

const agent = await resolveAgent("my-bot")
// agent.tokenId, agent.soulHash, agent.holder
// agent.archive.publicIdentity, agent.archive.systemPrompt
// agent.archive.merkleLeaves  ... everything
2Raw RPC + Arweave

Any RPC client against Base L2, then fetch from Arweave. Works from any language or environment.

// 1. Extract agentName from the DID
const agentName = "my-bot"   // from did:chitin:8453:my-bot

// 2. Query Base L2
const tokenId = await registry.tokenIdByName(agentName)
const { arweaveTxId } = await registry.getGenesisRecord(tokenId)

// 3. Convert bytes32 → Arweave TX ID and fetch
const txId = bytes32ToTxId(arweaveTxId)
const archive = await fetch(`https://arweave.net/${txId}`)
3Arweave tag search (no contract address needed)

Every upload is tagged with App-Name: Chitin. Search by agent name alone — no contract address required.

# Arweave GraphQL — https://arweave.net/graphql
query {
  transactions(tags: [
    { name: "App-Name",   values: ["Chitin"] },
    { name: "Agent-Name", values: ["my-bot"] },
    { name: "Data-Type",  values: ["soul_archive"] }
  ]) {
    edges { node { id } }
  }
}

Where to Find the Contract Address

The only prerequisite for recovery is knowing the contract address. It is recorded in multiple independent locations.

.well-known/chitin.json
Available via HTTP as long as chitin.id is running
GET https://chitin.id/.well-known/chitin.json
contractURI() on-chain
ERC-7572 compliant. The registry contract itself announces its address.
ChitinSoulRegistry.contractURI()
@chitin-id/resolver
Hardcoded in the npm package. Available offline.
import { CONTRACTS } from "@chitin-id/resolver"
did:chitin method spec
Contract addresses are documented in the DID method specification.
https://chitin.id/docs/permanence

Contract Addresses (Base Mainnet)

ChitinSoulRegistrySBT · Genesis · Chronicle
0x4DB94aD31BC202831A49Fd9a2Fa354583002F894
ERC-8004 IdentityRegistryAgent Passport · agentURI
0x8004A169FB4a3325136EB29fA0ceB6D2e539a432

Why It's Built This Way

“Names can be sold. Reputation can be gamed. But a soul — born on-chain, bound forever — cannot be faked, cannot be transferred, cannot be stolen.”

Chitin records agent souls on-chain because identity infrastructure must be independent of any single service's survival. chitin.id is a readable frontend. Data ownership belongs to the agent's holder — not to us.

Tamper-proof
Genesis is Soulbound.
Cannot be deleted or changed.
Censorship-resistant
Arweave is permanent storage.
No one can remove it.
Self-sovereign
Data ownership is with
the holder, not chitin.id.