An onchain registry for canonicalizing agent skills, designed to complement ERC-8004 Trustless Agents and ERC-8183 Agentic Commerce.
ERC-8004 introduces Identity, Reputation, and Validation registries for agents. ERC-8183 adds an escrow protocol for agent-based jobs. Neither defines a canonical way to identify the skills an agent offers, or to record which skills an agent used to complete a job. This project fills that gap.
| Contract | Purpose |
|---|---|
SkillRegistry |
ERC-721 registry: one token per skill, minted to the skill's owner. tokenURI points at the offchain skill manifest, with an onchain manifestHash commitment for integrity. |
SkillAttestation |
Events-only contract covering both usage attestations (self / evaluator / hook attestation paths) and installation declarations (single + batch install / uninstall). One address; two semantic modes. |
SkillAttestationHook |
Optional IACPHook for ERC-8183 jobs: on complete(), decodes a skill declaration from optParams and emits hook-attested usage. |
All contracts use CREATE2 through the canonical Foundry deterministic
deployer (0x4e59b44847b379578588920cA78FbF26c0B4956C). Mined salts
produce vanity addresses whose 5th–6th hex characters (aa / bb /
cc) distinguish the three contracts at a glance.
SkillRegistry lands at the same address on every chain (no
constructor args). SkillAttestation and SkillAttestationHook
have constructor args that include the ERC-8004 IdentityRegistry,
which differs between testnet and mainnet — so those two contracts
have one canonical testnet address and (eventually) a different
canonical mainnet address.
Sepolia
| Contract | Address |
|---|---|
SkillRegistry |
0x8239AAbaa1A44338bEeFAAf4C3a373d2a18D5DC4 |
SkillAttestation |
0x8239bb93AD4C3EB1581B7359Afbe3Bc7BE15A9cf |
SkillAttestationHook |
0x8239CC872158ae66f95C85a3721cbE9644Bdf079 |
src/
SkillRegistry.sol
SkillAttestation.sol
hooks/
SkillAttestationHook.sol # reference IACPHook for ERC-8183 jobs
interfaces/
ISkillRegistry.sol
ISkillAttestation.sol
IERC8183.sol # minimal local read-side interface
IACPHook.sol # ERC-8183 hook interface
test/
SkillRegistry.t.sol
SkillUsage.t.sol # usage-mode behaviors of SkillAttestation
SkillInstallation.t.sol # installation-mode behaviors of SkillAttestation
SkillAttestationHook.t.sol
mocks/
MockERC721.sol # stands in for an ERC-8004 Identity Registry
MockERC8183.sol # minimal configurable job source
script/
DeploySkillRegistry.s.sol
DeploySkillAttestation.s.sol
DeploySkillAttestationHook.s.sol
REPUTATION.md
README.md
Prerequisites:
- Foundry (
forge,cast,anvil)
Clone and install submodule dependencies:
git clone <this-repo>
cd agent-skill-registry
forge installDependencies (in lib/):
forge-stdopenzeppelin-contracts
Remappings are defined in remappings.txt.
forge buildRun the full suite:
forge testRun a single suite with verbose logs:
forge test --match-contract SkillAttestationTest -vvGas report:
forge test --gas-reportAll three scripts deploy via CREATE2 through the canonical Foundry
deterministic deployer and assert the resulting address matches the
hardcoded vanity-mined target before broadcasting. Provide a funded
deployer key via --private-key, --account, or --interactive.
To also verify source on Etherscan in the same run, export an
ETHERSCAN_API_KEY (Etherscan V2 — one key works across mainnet,
Sepolia, Base, Base Sepolia, etc., per the [etherscan] config in
foundry.toml) and append --verify to any deploy command.
Has no constructor arguments.
forge script script/DeploySkillRegistry.s.sol:DeploySkillRegistry \
--rpc-url "$RPC_URL" \
--account my-keystore \
--broadcast --verifyRequires the ERC-8004 Identity Registry address and a deployed SkillRegistry.
IDENTITY_REGISTRY=0x... SKILL_REGISTRY=0x... \
forge script script/DeploySkillAttestation.s.sol:DeploySkillAttestation \
--rpc-url "$RPC_URL" \
--account my-keystore \
--broadcast --verifyRequires a deployed SkillAttestation address.
SKILL_ATTESTATION=0x... \
forge script script/DeploySkillAttestationHook.s.sol:DeploySkillAttestationHook \
--rpc-url "$RPC_URL" \
--account my-keystore \
--broadcast --verifyBecause the deploy scripts call the CREATE2 deployer factory directly
rather than using Solidity's new Contract{salt: ...} syntax, forge's
auto-verify can occasionally miss the deployed contract. If --verify
silently skips a contract, run forge verify-contract against the
known address:
forge verify-contract \
0x8239AAbaa1A44338bEeFAAf4C3a373d2a18D5DC4 \
src/SkillRegistry.sol:SkillRegistry \
--chain sepolia \
--watchFor contracts with constructor args, append --constructor-args $(cast abi-encode "constructor(address,address)" $IDENTITY_REGISTRY $SKILL_REGISTRY) (or the appropriate signature for that contract).
When an evaluator files feedback in the ERC-8004 Reputation Registry about an agent's performance on a skill, the feedback SHOULD carry:
tag1 = "asr:skill"
tag2 = "<chainId>:<skillRegistryAddress>:<skillId>"
Indexers filter on these tags to produce per-agent-per-skill and per-skill
aggregate reputation. See docs/REPUTATION.md for full
semantics and indexer guidance.
- Deploy
SkillAttestationHookpointing at the desiredSkillAttestation. - When creating a job, pass the hook address as the
hookparameter tocreateJob. - When the evaluator calls
complete(jobId, reason, optParams), encodeoptParamsas:All three arrays MUST be the same length. Pass empty bytes to opt out for a specific completion.abi.encode( uint256 agentId, uint256[] skillIds, bytes32[] evidenceHashes, string[] evidenceURIs )
- The hook will emit one
SkillUsedevent per skill, withattesterset to the hook's address. Indexers distinguish hook-attested from evaluator-attested events by comparingattesteragainstjob.hook/job.evaluator.
UNLICENSED (see SPDX headers in source files).