API Reference
Every external function on the ERC-8004 Identity Adapter.
All functions live on Adapter8004 (src/Adapter8004.sol).
Exact parameter types track the contract source — check the repo if a
signature changes.
Initialization#
initialize(address identityRegistry_, address initialOwner)#
UUPS initializer. Called once via the proxy. Reverts with InvalidTokenContract
if identityRegistry_ is zero and with OwnableInvalidOwner if initialOwner
is zero. The implementation's constructor calls _disableInitializers(), so
the bare implementation cannot be initialized.
Registration#
register(TokenStandard, address tokenContract, uint256 tokenId, string agentURI, MetadataEntry[] metadata) → uint256 agentId#
Registers a new ERC-8004 identity and binds it to (standard, tokenContract, tokenId). Reverts with:
InvalidTokenContract—tokenContract == address(0)NotController— caller does not currently control the external token
Emits AgentBound(agentId, standard, tokenContract, tokenId, registeredBy).
After registration the adapter calls unsetAgentWallet(agentId) on the
registry to clear the default agentWallet slot.
Controller-gated writes#
Every function below calls _requireController(agentId, msg.sender), which
reverts with UnknownAgent(agentId) if the id was never bound and
NotController(account, agentId) if the caller does not currently control
the bound token.
setAgentURI(uint256 agentId, string newURI)#
Forwards to identityRegistry.setAgentURI.
setMetadata(uint256 agentId, string key, bytes value)#
Forwards to identityRegistry.setMetadata.
setMetadataBatch(uint256 agentId, MetadataEntry[] metadata)#
Loops over metadata and forwards each entry to
identityRegistry.setMetadata. Emits MetadataBatchSet(agentId, count, updatedBy) after the loop. The count can be zero — the event still fires.
setAgentWallet(uint256 agentId, address newWallet, uint256 deadline, bytes signature)#
Forwards to identityRegistry.setAgentWallet. The registry enforces the
wallet-proof rule — see Concepts
for the EIP-712 owner subtlety.
unsetAgentWallet(uint256 agentId)#
Forwards to identityRegistry.unsetAgentWallet. Idempotent.
Views#
bindingOf(uint256 agentId) → Binding#
Returns the Binding struct. Reverts with UnknownAgent(agentId) if the
binding does not exist.
agentIdForBinding(TokenStandard, address tokenContract, uint256 tokenId) → (uint256 agentId, bool exists)#
Reverse lookup. Returns (0, false) if no binding exists. Because the adapter
stores bindings as agentId + 1 internally, agentId = 0 is correctly
distinguished from "unset" — the boolean is the source of truth.
isController(uint256 agentId, address account) → bool#
Returns true iff the bound token contract currently reports account as a
holder per the standard's control rule. Returns false (no revert) if the
agentId is unknown. This is the safe query to use before attempting a
controller-gated write.
Admin#
setIdentityRegistry(address newRegistry)#
onlyOwner. Reverts with InvalidTokenContract if newRegistry is zero.
Emits IdentityRegistryUpdated(previous, new, updatedBy).
Previously-registered bindings remain in the adapter's storage but writes targeted at their agentIds will now route into the new registry — which has no knowledge of those ids. See Admin & Upgrades for the operational implications.
upgradeToAndCall(address newImplementation, bytes data) (from UUPS)#
Owner-only. Gated by _authorizeUpgrade(onlyOwner). Renouncing ownership via
renounceOwnership() permanently disables upgrades and registry swaps.
ERC-721 receiver#
onERC721Received(address, address, uint256, bytes) → bytes4#
Returns IERC721Receiver.onERC721Received.selector. The adapter never calls
safeTransferFrom against the external bound token, but it implements the
interface so it can receive the ERC-8004 token from the registry on register.
Errors#
| Error | When |
|---|---|
InvalidTokenContract() | Zero address passed as registry or tokenContract |
NotController(address account, uint256 agentId) | Caller isn't the current controller |
UnknownAgent(uint256 agentId) | agentId was never bound |
BindingAlreadyExists(...) | Binding slot already taken (depending on revision) |
OwnableUnauthorizedAccount(address) | Non-owner hitting an admin function |
OwnableInvalidOwner(address) | Zero address passed as initialOwner |
InvalidInitialization() | Re-initialization attempt |
Events#
| Event | Fired by |
|---|---|
AgentBound(agentId, standard, tokenContract, tokenId, registeredBy) | register |
MetadataBatchSet(agentId, count, updatedBy) | setMetadataBatch |
IdentityRegistryUpdated(previous, new, updatedBy) | setIdentityRegistry |
OwnershipTransferred(...) | Inherited from OwnableUpgradeable |
Upgraded(newImplementation) | Inherited from UUPS |