Integrations
Karatum certificate status over Hyperlane (testnets)
On this page
All documents
Methodology
- Agent Honesty Index (AHI) — methodology
- Verifiable judge: who checks the checker?
- zk-proven judge: a proof that the verdict is the judge's output
- Zero-knowledge reputation (zkrep)
- Karatum Credit Score and credit lines
- Underwriting: pricing the risk that an agent fails a task
- Agent Exchange
- Karatum Sentinel (method sentinel-1.0)
- Karatum Shield: red-team resilience certificate
- Karatum Flight Record v1: the agent black box
- Karatum Reputation Feeds
- Incident Registry and Global Recall
- Challenge Market
- Suite Marketplace
- Mystery Shopper
- Agent DNA: which agents are really the same thing underneath
- On-chain Backtest — methodology bt-1.0
- Protocol Agent-Readiness Audit
- Compliance Evidence Pack
Specifications
Integrations
- Karatum for Minds agents and Moca AIR agentic commerce
- Karatum agent scores as Chainlink-style data feeds (testnets)
- ENS: <build>.karatum.eth (Ethereum Sepolia, testnet)
- Karatum certificate status over Hyperlane (testnets)
- Karatum × Lit Protocol: only certified agents may decrypt or act
- Minds, Moca AIR and Moca Chain: what builders can use (research, 2026-10-16)
Source files
Status: testnet pilot. Ethereum Sepolia → Base Sepolia, Arbitrum Sepolia, OP Sepolia. Contracts, addresses and the
recorded end-to-end runs are in contracts/deployments/hyperlane.json.
What it does
When Karatum revokes (or reinstates) an agent's certificate, the change used to reach other chains only through Karatum's
own direct transactions on each chain (Guard KaratumCertRegistry.revokeCert, KaratumIncidentLog, the reputation feed).
That needs a funded Karatum key on every chain and makes every chain trust that key.
With Hyperlane, Karatum signs one transaction on the home chain. KaratumStatusHub records the new status and
dispatches it through Hyperlane's canonical Mailbox to a KaratumStatusMirror on each destination. Hyperlane's public
relayer delivers the message; the destination Mailbox verifies it with its ISM and calls the mirror. A contract on the
destination reads isRevoked(agent) or statusOf(agent) from the mirror. No Karatum key exists on the destination
for this path.
incident key ──broadcast()──▶ KaratumStatusHub (Sepolia) ──dispatch()──▶ Mailbox (Sepolia)
│ Hyperlane validators sign the
│ merkle checkpoint; relayer delivers
▼
consumer ──isRevoked()──▶ KaratumStatusMirror ◀──handle()── Mailbox (Base / Arbitrum / OP Sepolia) + default ISMIt is additive: the direct transactions still go out. The Hyperlane path is a second, independent route.
Contracts (contracts/src/hyperlane/)
| Contract | Where | Role |
|---|---|---|
KaratumStatusHub | Ethereum Sepolia | Authoritative record. broadcast(agent, status, reason, drill, handleGas) (broadcaster only) bumps the agent's nonce, stores the record and dispatches one message per configured route, paying each message's Mailbox.quoteDispatch fee and refunding any excess in the same transaction. rebroadcast re-sends the current record (same nonce) to chosen routes, for a newly added mirror or a message that has to be paid again. quoteBroadcast returns the total fee. |
KaratumStatusMirror | each destination | handle() accepts a message only when the caller is the Mailbox, the origin is the home domain (11155111) and the sender is the hub. Mailbox, home domain and hub are immutable. Within an agent's lane only a strictly higher nonce is applied. Older or replayed updates are ignored with StaleUpdateIgnored; they are not reverted, so a late message can't be retried forever and can't roll the state back. Malformed messages revert. ETH is refused. |
KaratumStatusCodec | library | Wire format v1: abi.encode(uint8 version, address agent, uint8 status, bool drill, uint64 nonce, uint64 updatedAt, bytes32 reason), 224 bytes. |
Status codes: 0 unknown (never broadcast), 1 VALID, 2 REVOKED. reason is the incident hash
keccak256("KAR-YYYY-NNNN") (or 0). updatedAt is the hub block time and receivedAt is the mirror's delivery block
time, so receivedAt - updatedAt is the bridge latency.
Drill lane. Every agent has two independent records with separate nonces: live and drill. A drill broadcast is a
rehearsal of the recall mechanism. It writes only drillStatusOf, so it can't overwrite or clear a real revocation,
and isRevoked never reports it.
Ownership. All contracts use Ownable2Step with owner 0xa4AB…Af43, and renouncing is disabled. On the hub the owner
can rotate the broadcaster and the routes. On a mirror the owner can only change the ISM. The broadcaster is the
incident key (0x6358…b508).
Gas. Each message carries StandardHookMetadata (variant 1, msg.value 0, gas limit, refund address = caller). The
default handle gas limit is 150,000; a first write measures about 70k. The fee is whatever the Mailbox quotes for that
metadata (default hook plus the IGP payment). On 2026-10-27 three routes cost about 4.6e-5 ETH in total.
Reading it from a consumer contract
interface IKaratumAgentStatus {
function isRevoked(address agent) external view returns (bool);
function statusOf(address agent) external view returns (uint8 status, uint64 nonce, uint64 updatedAt, uint64 receivedAt, bytes32 reason);
}
require(!IKaratumAgentStatus(KARATUM_MIRROR).isRevoked(agent), "Karatum: certificate revoked");Reading isRevoked from the hub on Sepolia gives the same answer as reading it from any mirror once delivery completes.
A mirror can't speed up a revocation: until the relayer delivers, a mirror shows the previous status. Consumers that
need a freshness bound should check updatedAt.
Security model and switching to a stricter ISM
The mirrors start on the Mailbox default ISM (interchainSecurityModule() returns address(0)): Hyperlane's own
testnet validator set for the Sepolia origin. A message reaches handle() only if that ISM verified it. The mirror then
also checks the origin domain and the hub address, so a valid message from any other sender is rejected.
On top of that, Karatum can pin its own ISM on each mirror. Only the owner can do it:
- Run validators for the Sepolia origin. Run one or more Hyperlane validator agents watching the Sepolia
MerkleTreeHook(0x4917a974…2d0d). Each one announces its checkpoint storage location (S3 or GCS) on the SepoliaValidatorAnnounce(0xE6105C59…CfCD9), which is how relayers find its signatures. - Deploy a multisig ISM on each destination with Hyperlane's static factory, which needs no code of our own. For
example on Base Sepolia (
staticMessageIdMultisigIsmFactory0xfc6e5465…B213):cast send 0xfc6e546510dC9d76057F1f76633FCFfC188CB213 "deploy(address[],uint8)" "[0xVAL1,0xVAL2,0xVAL3]" 2 --rpc-url $BASE_SEPOLIA_RPC # the ISM address is the return value / the factory's deploy event; `cast call <factory> "getAddress(address[],uint8)(address)" ...` predicts itFor defence in depth, require both Hyperlane's default ISM and Karatum's multisig. To do that, build an aggregation ISM with
staticAggregationIsmFactory.deploy([defaultIsm, karatumMultisigIsm], 2). The default ISM addresses are listed undermirrors.*.defaultIsmin the deployment file. - Pin it:
KaratumStatusMirror.setInterchainSecurityModule(ism)from the owner on that chain. To revert to the Mailbox default, pinaddress(0). Check the result withpnpm --filter @karatum/incidents-service hyperlane config. - Relaying. Hyperlane's public relayer delivers to a recipient with a custom ISM only if it can fetch the
signatures that ISM needs. Validators announced on-chain (step 1) are usually enough. If not, run a Hyperlane
relayer restricted to the hub as sender (whitelist
{"originDomain": 11155111, "senderAddress": "<hub>"}).
Important: pin the new ISM only after its validators are signing. If you pin it earlier, every message stays
undeliverable until they do. Messages queued in that window are not lost: the relayer retries, or the broadcaster sends
rebroadcast.
Limitations (pilot)
- One status per agent per lane. The hub doesn't keep a set of active incidents per agent the way
KaratumIncidentLogdoes. If two incidents recall the same agent and the later one is fixed first, its lift reinstates the agent in the mirror even though the earlier incident is still active. The lift rule above covers the common order; the full fix is to have the hub derive status from per-incident recalls. - Delivery depends on Hyperlane's public testnet relayer. It has no SLA. Undelivered messages stay pending and can be
re-paid with
rebroadcast. - The OP Sepolia mirror was deployed by the feed-updater key. The owner key holds no OP Sepolia ETH; ownership was set in the constructor. The owner needs OP Sepolia ETH before it can pin an ISM there.
- Testnet only. A mainnet hub needs a mainnet ISM decision first (a Karatum multisig aggregated with the default ISM) and a separate broadcaster key.