@onchainsupply/identity
v0.1.0
Published
Modular identity primitives for the Onchain Supply stack. The package ships a Solidity `IdentityRegistry` contract that assigns human-friendly names to onchain subjects (accounts, content digests, shortlinks, workspaces, or any category you define). It en
Readme
@onchainsupply/identity
Modular identity primitives for the Onchain Supply stack. The package ships a Solidity IdentityRegistry contract that assigns human-friendly names to onchain subjects (accounts, content digests, shortlinks, workspaces, or any category you define). It enforces category-scoped uniqueness, supports registrar roles, and exposes update and transfer workflows so downstream apps (e.g. OnChainDrive) can keep identity metadata up to date.
Features
- Registry-first design – categories (32-byte identifiers) isolate namespaces such as
content,account, or bespoke verticals. Each subject (bytes32) maps to aNameRecord. - Configurable access – grant
REGISTRAR_ROLEto trusted contracts, or enable public registration per category when self-service naming makes sense. - Uniqueness guarantees – case-insensitive hashing prevents duplicate labels inside a category.
- Lifecycle management – owners (or registrars) can rename, transfer ownership, or release names.
- Integration helpers – companion libraries (
IdentityConstants,IdentitySubjects) simplify deriving category identifiers and subject keys from common data.
Contracts
| Contract | Description |
| --- | --- |
| IdentityRegistry.sol | Core registry storing NameRecord structs keyed by category and subject. Emits lifecycle events for registration, updates, transfers, and releases. |
| libraries/IdentityConstants.sol | Predefined category identifiers for common use cases (accounts, content, workspaces, shortlinks). |
| libraries/IdentitySubjects.sol | Helper functions to convert addresses, multihash digests, or arbitrary bytes into 32-byte subjects. |
| interfaces/IIdentityRegistry.sol | Interface consumed by external integrations (e.g. OnChainDrive). |
Usage
import {IdentityRegistry} from "@onchainsupply/identity/contracts/IdentityRegistry.sol";
import {IdentityConstants} from "@onchainsupply/identity/contracts/libraries/IdentityConstants.sol";
import {IdentitySubjects} from "@onchainsupply/identity/contracts/libraries/IdentitySubjects.sol";
contract Example {
IdentityRegistry public immutable identities;
constructor(IdentityRegistry registry) {
identities = registry;
}
function registerContent(bytes32 digest, string calldata name) external {
identities.register(
IdentityConstants.CATEGORY_CONTENT,
IdentitySubjects.contentSubject(digest),
name,
msg.sender
);
}
}Categories
Pass any bytes32 identifier to create a namespace. The constructor accepts an initial list and you can call setCategoryConfig later to toggle public registration or uniqueness enforcement per category.
bytes32[] memory categories = new bytes32[](3);
categories[0] = IdentityConstants.CATEGORY_ACCOUNT;
categories[1] = IdentityConstants.CATEGORY_CONTENT;
categories[2] = IdentityConstants.CATEGORY_SHORTLINK;
IdentityRegistry registry = new IdentityRegistry(msg.sender, categories);
registry.setCategoryConfig(IdentityConstants.CATEGORY_ACCOUNT, true, true); // allow self-service account namesRoles
DEFAULT_ADMIN_ROLE– can configure categories and grant/revoke roles.REGISTRAR_ROLE– can register/rename/transfer on behalf of users.
Without a registrar role, users can only interact with categories that have publicRegistration enabled and must be the name owner.
Events
NameRegistered(bytes32 category, bytes32 subject, string name, address owner)NameUpdated(bytes32 category, bytes32 subject, string oldName, string newName, address owner)NameOwnerTransferred(bytes32 category, bytes32 subject, address newOwner)NameReleased(bytes32 category, bytes32 subject, string name)CategoryConfigured(bytes32 category, bool publicRegistration, bool enforceUniqueNames)
Scripts & Tests
Run the test suite (Solidity via Foundry-compatible harness + node-based viem tests):
pnpm install
pnpm testKey test: test/IdentityRegistry.ts covers registrar gating, uniqueness enforcement, ownership transfers, updates, and release flows.
Publishing
The package is ready to publish to npm as @onchainsupply/identity. A typical release pipeline:
pnpm build # hardhat compile
npm publish --access publicpackage.json lists the contract sources as publishable files. Consumer projects can then add the dependency and import the contracts directly.
