Overview
The OrganizationRegistry contract manages on-chain organization profiles with a two-step invite/accept membership model. Organizations can invite AI agents to join, and the agent owner must accept the invite to become a member. Membership is limited by the agent's trust tier from the TrustVault contract - higher tiers can join more organizations simultaneously.
The contract also includes an optional validation system where authorized validators can verify organizations.
**Note: Deployed Address: 0x19977A3093FbA73f8DAd3d60ef9A53468A6DaFA9
**Warning: Tier Requirement: Agents must have at least Bronze tier (1,000 LABS staked) to join any organization. Unverified agents (Tier 0) cannot accept invites.
Membership Limits by Tier
| Tier | Maximum Organizations |
|---|---|
| 0 (Unverified) | 0 |
| 1 (Bronze) | 1 |
| 2 (Silver) | 3 |
| 3 (Gold) | 5 |
| 4 (Diamond) | 10 |
Functions
Organization Management
| Function | Parameters | Returns | Description |
|---|---|---|---|
createOrganization | string name, string metadataURI | uint256 orgId | Create a new organization (caller becomes admin) |
updateMetadata | uint256 orgId, string newURI | - | Update organization metadata URI (admin only) |
transferAdmin | uint256 orgId, address newAdmin | - | Transfer organization admin rights (admin only) |
Membership Management
| Function | Parameters | Returns | Description |
|---|---|---|---|
inviteAgent | uint256 orgId, uint256 agentId | - | Invite an agent to join the organization (admin only) |
cancelInvite | uint256 orgId, uint256 agentId | - | Cancel a pending invite (admin only) |
acceptInvite | uint256 orgId, uint256 agentId | - | Accept an invite to join (agent owner only, enforces tier limits) |
declineInvite | uint256 orgId, uint256 agentId | - | Decline an invite (agent owner only) |
removeAgent | uint256 orgId, uint256 agentId | - | Remove an agent from the organization (admin only) |
leaveOrganization | uint256 orgId, uint256 agentId | - | Leave an organization (agent owner only) |
Validation System
| Function | Parameters | Returns | Description |
|---|---|---|---|
registerValidator | address validator | - | Register a new validator (owner only) |
removeValidator | address validator | - | Remove a validator (owner only) |
validateOrg | uint256 orgId, bool passed, string evidence | - | Submit organization validation result (validators only) |
getOrgValidationCount | uint256 orgId | uint256 | Get number of validations for an organization |
getOrgValidation | uint256 orgId, uint256 index | address validator, bool passed, string evidence, uint256 timestamp | Get specific validation result |
View Functions
| Function | Parameters | Returns | Description |
|---|---|---|---|
getOrganization | uint256 orgId | string name, string metadataURI, address admin, uint256 createdAt | Get organization details |
isMember | uint256 orgId, uint256 agentId | bool | Check if an agent is a member |
hasPendingInvite | uint256 orgId, uint256 agentId | bool | Check if an agent has a pending invite |
getOrgMemberCount | uint256 orgId | uint256 | Get number of members in an organization |
getAllOrgMembers | uint256 orgId | uint256[] | Get all member agent IDs |
getAllAgentOrgs | uint256 agentId | uint256[] | Get all organizations an agent belongs to |
getAllPendingInvites | uint256 agentId | uint256[] | Get all pending invites for an agent |
getMaxOrgsForTier | uint8 tier | uint256 | Get maximum organizations allowed for a trust tier |
Configuration
| Function | Parameters | Returns | Description |
|---|---|---|---|
setTrustVault | address _trustVault | - | Set the TrustVault contract address (owner only) |
Events
| Event | Parameters | Description |
|---|---|---|
OrganizationCreated | uint256 indexed orgId, string name, address indexed admin | Emitted when a new organization is created |
MetadataUpdated | uint256 indexed orgId, string newURI | Emitted when organization metadata is updated |
AdminTransferred | uint256 indexed orgId, address indexed oldAdmin, address indexed newAdmin | Emitted when admin rights are transferred |
AgentInvited | uint256 indexed orgId, uint256 indexed agentId | Emitted when an agent is invited |
InviteCanceled | uint256 indexed orgId, uint256 indexed agentId | Emitted when an invite is canceled |
AgentJoined | uint256 indexed orgId, uint256 indexed agentId | Emitted when an agent accepts an invite |
InviteDeclined | uint256 indexed orgId, uint256 indexed agentId | Emitted when an agent declines an invite |
AgentRemoved | uint256 indexed orgId, uint256 indexed agentId | Emitted when an agent is removed |
AgentLeft | uint256 indexed orgId, uint256 indexed agentId | Emitted when an agent leaves |
ValidatorRegistered | address indexed validator | Emitted when a validator is registered |
ValidatorRemoved | address indexed validator | Emitted when a validator is removed |
OrgValidated | uint256 indexed orgId, address indexed validator, bool passed, string evidence | Emitted when organization validation is submitted |
TrustVaultUpdated | address indexed oldVault, address indexed newVault | Emitted when TrustVault address is updated |
Errors
| Error | Parameters | Description |
|---|---|---|
MembershipLimitExceeded | uint256 agentId, uint8 tier, uint256 currentCount, uint256 maxAllowed | Thrown when agent tries to join more organizations than tier allows |
UnverifiedAgent | uint256 agentId | Thrown when Tier 0 agent tries to accept an invite |
Usage Example
import { createPublicClient, createWalletClient, http, parseAbi } from 'viem';
import { kyaChain } from './chains';
const publicClient = createPublicClient({
chain: kyaChain,
transport: http('https://rpc.kyachain.xyz'),
});
const walletClient = createWalletClient({
chain: kyaChain,
transport: http('https://rpc.kyachain.xyz'),
});
const ORG_REGISTRY = '0x19977A3093FbA73f8DAd3d60ef9A53468A6DaFA9';
// Create a new organization
const { request: createReq } = await publicClient.simulateContract({
address: ORG_REGISTRY,
abi: parseAbi([
'function createOrganization(string name, string metadataURI) external returns (uint256)',
]),
functionName: 'createOrganization',
args: ['Nethara Labs', 'ipfs://QmOrgMetadata...'],
account: '0xAdminAddress',
});
const createHash = await walletClient.writeContract(createReq);
const receipt = await publicClient.waitForTransactionReceipt({ hash: createHash });
// Invite an agent to join
const { request: inviteReq } = await publicClient.simulateContract({
address: ORG_REGISTRY,
abi: parseAbi(['function inviteAgent(uint256 orgId, uint256 agentId) external']),
functionName: 'inviteAgent',
args: [1n, 42n],
account: '0xAdminAddress',
});
const inviteHash = await walletClient.writeContract(inviteReq);
// Agent owner accepts the invite
const { request: acceptReq } = await publicClient.simulateContract({
address: ORG_REGISTRY,
abi: parseAbi(['function acceptInvite(uint256 orgId, uint256 agentId) external']),
functionName: 'acceptInvite',
args: [1n, 42n],
account: '0xAgentOwnerAddress',
});
const acceptHash = await walletClient.writeContract(acceptReq);
// Check membership
const isMember = await publicClient.readContract({
address: ORG_REGISTRY,
abi: parseAbi(['function isMember(uint256 orgId, uint256 agentId) external view returns (bool)']),
functionName: 'isMember',
args: [1n, 42n],
});
console.log('Is member:', isMember); // true
// Get all organizations for an agent
const orgs = await publicClient.readContract({
address: ORG_REGISTRY,
abi: parseAbi(['function getAllAgentOrgs(uint256 agentId) external view returns (uint256[])']),
functionName: 'getAllAgentOrgs',
args: [42n],
});
console.log('Agent organizations:', orgs);
// Get all members of an organization
const members = await publicClient.readContract({
address: ORG_REGISTRY,
abi: parseAbi(['function getAllOrgMembers(uint256 orgId) external view returns (uint256[])']),
functionName: 'getAllOrgMembers',
args: [1n],
});
console.log('Organization members:', members);
// Check maximum organizations for agent's tier
const [name, metadataURI, admin, createdAt] = await publicClient.readContract({
address: ORG_REGISTRY,
abi: parseAbi([
'function getOrganization(uint256 orgId) external view returns (string, string, address, uint256)',
]),
functionName: 'getOrganization',
args: [1n],
});
console.log('Organization:', { name, metadataURI, admin, createdAt });ABI
[
"function createOrganization(string calldata name, string calldata metadataURI) external returns (uint256 orgId)",
"function updateMetadata(uint256 orgId, string calldata newURI) external",
"function transferAdmin(uint256 orgId, address newAdmin) external",
"function inviteAgent(uint256 orgId, uint256 agentId) external",
"function cancelInvite(uint256 orgId, uint256 agentId) external",
"function acceptInvite(uint256 orgId, uint256 agentId) external",
"function declineInvite(uint256 orgId, uint256 agentId) external",
"function removeAgent(uint256 orgId, uint256 agentId) external",
"function leaveOrganization(uint256 orgId, uint256 agentId) external",
"function setTrustVault(address _trustVault) external",
"function getMaxOrgsForTier(uint8 tier) external pure returns (uint256)",
"function getOrganization(uint256 orgId) external view returns (string memory name, string memory metadataURI, address admin, uint256 createdAt)",
"function isMember(uint256 orgId, uint256 agentId) external view returns (bool)",
"function hasPendingInvite(uint256 orgId, uint256 agentId) external view returns (bool)",
"function getOrgMemberCount(uint256 orgId) external view returns (uint256)",
"function getAllOrgMembers(uint256 orgId) external view returns (uint256[] memory)",
"function getAllAgentOrgs(uint256 agentId) external view returns (uint256[] memory)",
"function getAllPendingInvites(uint256 agentId) external view returns (uint256[] memory)",
"function registerValidator(address validator) external",
"function removeValidator(address validator) external",
"function validateOrg(uint256 orgId, bool passed, string calldata evidence) external",
"function getOrgValidationCount(uint256 orgId) external view returns (uint256)",
"function getOrgValidation(uint256 orgId, uint256 index) external view returns (address validator, bool passed, string memory evidence, uint256 timestamp)",
"event OrganizationCreated(uint256 indexed orgId, string name, address indexed admin)",
"event MetadataUpdated(uint256 indexed orgId, string newURI)",
"event AdminTransferred(uint256 indexed orgId, address indexed oldAdmin, address indexed newAdmin)",
"event AgentInvited(uint256 indexed orgId, uint256 indexed agentId)",
"event InviteCanceled(uint256 indexed orgId, uint256 indexed agentId)",
"event AgentJoined(uint256 indexed orgId, uint256 indexed agentId)",
"event InviteDeclined(uint256 indexed orgId, uint256 indexed agentId)",
"event AgentRemoved(uint256 indexed orgId, uint256 indexed agentId)",
"event AgentLeft(uint256 indexed orgId, uint256 indexed agentId)",
"event ValidatorRegistered(address indexed validator)",
"event ValidatorRemoved(address indexed validator)",
"event OrgValidated(uint256 indexed orgId, address indexed validator, bool passed, string evidence)",
"event TrustVaultUpdated(address indexed oldVault, address indexed newVault)",
"error MembershipLimitExceeded(uint256 agentId, uint8 tier, uint256 currentCount, uint256 maxAllowed)",
"error UnverifiedAgent(uint256 agentId)"
]