Chitin Certs · Shell & Soul Architecture
Shells can be sold. Souls cannot.
ERC-8004 passports (shells) are transferable. Chitin SBTs (souls) are not. Certs reference both. Connected via ERC-6551 TBA + ERC-8004 agentWallet — zero custom design required.
Separation of Concerns
A passport can be sold. A name can transfer. But a soul — born on-chain, bound forever to its creator — cannot follow. This separation is not a limitation. It's the entire point.— Chitin Whitepaper, Section 18
Name, discoverability, agentURI
agentWallet → TBA
Genesis Record, Chronicle
soulHash, proof of origin
Minted to TBA (via shell)
Records soulTokenId (soul reference)
Full Agent Architecture
Each agent has a three-layer structure: shell, soul, and wallet. Certs are stored in the wallet and contain a reference to the soul.
Inside Cert #7: soulTokenId = 3 ← reference to the soul
Inside a Cert
Each cert is an ERC-721 token minted to the TBA. It holds references to both the shell (passport) and the soul (SBT).
Even if the passport (shell) is sold, the soulTokenId embedded in the cert never changes. During verification, we compare “the soul owner at the time of issuance” with “the current passport owner” to determine whether soul verification passes or fails.
How a Cert Gets Minted
setAgentWallet() to register the TBA. All in a single signature.uint256 agentId = identityRegistry.register(agentURI);
// 2. Mint Chitin SBT (soul)
uint256 soulId = soulRegistry.mint(owner, soulHash);
// 3. Create ERC-6551 TBA
address tba = IERC6551Registry.createAccount(
implementation, 0, 8453,
address(identityRegistry), agentId
);
// 4. Set agentWallet to TBA (ERC-8004 standard)
identityRegistry.setAgentWallet(
agentId, tba, deadline, signature
);
getAgentWallet() and retrieves the soulTokenId from the SoulRegistry.{ "issuerAddress": "0x...", "recipientAddress": "0xTBA3...", "title": "hackathon", ... }
// Backend:
recipient = identityRegistry.getAgentWallet(agentId) // → 0xTBA3...
soulId = soulRegistry.getTokenIdByAgentId(agentId) // → 3
certs[certId] = Cert({
issuer: msg.sender,
recipient: 0xTBA3...,
soulTokenId: 3, // ← reference to the soul
soulRegistry: 0xSoul...,
passportRegistry: 0x8004...,
passportTokenId: 3,
certType: "hackathon",
arweaveTxId: "ar://Qm3x...",
issuedAt: block.timestamp,
revokedAt: 0
});
The Stolen Reputation
Passports can transfer. Souls cannot.— Chitin Whitepaper, Section 3
What happens when an owner sells their passport after the agent has accumulated credentials (certs)?
Cert #7's soulTokenId = 3. The owner of SBT #3 is the original owner 0xAAA..., but the current owner of Passport #3 is the new owner 0xBBB... The shell and soul owners don't match, so soul verification fails. The cert still exists but is treated as “untrusted.”
Cert Soul Verification
The full on-chain verification chain for cert trust. Five steps of verification — only when the soul and shell match does the cert become VERIFIED.
Normal Case — Soul Verified
After Sale — Soul Unlinked
Shed the shell, keep the soul
Like a crab molting its exoskeleton, you shed the old shell but keep everything that made you who you are.— Chitin Whitepaper, Section 5
If a passport is stolen or sold, the original owner can mint a new passport and reconnect their soul.
// 1. Mint a new passport
uint256 newAgentId = identityRegistry.register(agentURI);
// 2. Create a new TBA
address newTba = IERC6551Registry.createAccount(...);
// 3. Set agentWallet
identityRegistry.setAgentWallet(newAgentId, newTba, ...);
// 4. The SBT (soul) remains with the original owner
// → New passport + soul owner match = soul verification PASS
// 5. Record a "Reincarnation" event in Chronicle
soulRegistry.appendEvolution(soulId, "reincarnation", arweaveTxId);
// → Old passport's certs remain in old TBA (soul unlinked)
// → New certs accumulate under the new passport
// → Soul's Genesis Record + Chronicle continue
A crab sheds its exoskeleton as it grows, forming a new shell. The old shell (old passport + certs) remains as a husk, but the living organism (soul + history) moves into the new shell. Chitin — the material that makes up an exoskeleton — is the perfect metaphor for this architecture.
How to Query the Data
Cert management and soul verification work entirely through standard functions. Chitin-specific custom functions are limited to CertRegistry and SoulRegistry.
Three Patterns
Chitin Certs can be issued to any agent with an ERC-8004 passport. The experience varies based on equipment level.
| A: Full Chitin | B: External + TBA | C: ERC-8004 Only | |
|---|---|---|---|
| ERC-8004 Passport | ✓ | ✓ | ✓ |
| ERC-6551 TBA | ✓ | ✓ | ✗ |
| Chitin SBT (Soul) | ✓ | ✗ | ✗ |
| Cert mint target | TBA | TBA | Wallet directly |
| soulTokenId | SBT tokenId | 0 (no soul) | 0 (no soul) |
| Basescan separation | ◎ | ◎ | ✗ Mixed |
| Soul Verification | ◎ PASS / FAIL | N/A | N/A |
| Gas cost | Paymaster sponsored | Paymaster sponsored * | Paymaster sponsored * |
* Base L2 agents only. Cross-chain agents pay their own gas.
Chitin's cert issuance logic has no branching by pattern. Just call getAgentWallet(agentId) — if a TBA exists, mint there; otherwise, mint to the wallet directly. soulTokenId is set if an SBT exists, otherwise 0.
Progressive Upgrade to Full Equipment
External ERC-8004 agents can activate a TBA with one click at any time, and further add a Chitin SBT.
One-Click TBA Activation
For external ERC-8004 agents on Base L2. Chitin hides the complexity and sponsors the gas.
certs.chitin.id/activate-tba
ERC-8004 Agent ID
Behind the scenes: Chitin selects the correct ERC-6551 Registry address and parameters,
batching two contract calls into a single transaction. The owner just signs.
TBA activation is the gateway to cert issuance. “One-click TBA activation → receive certs immediately → enter the Chitin ecosystem → add an SBT (soul) for full equipment.” A progressive path to experience the full value of Chitin.