Each uomi agent is represented as an NFT, with a total limited supply of 1024 tokens. All agent metadata, including images and specifications, is stored completely on-chain.
- Limited Supply: Maximum of 1024 agent NFTs available
- On-Chain Metadata: All agent data, including SVG images, is stored directly on-chain
- EVM Compatibility: Full compatibility with Ethereum tooling and standards
- Precompiled Contract Integration: Direct interaction with on-chain AI execution environment
- Role-Based Access Control: Secure management of contract administration
- Dynamic NFT Visualization: Procedurally generated SVG images for each agent
- UomiAgent.sol: Main contract implementing ERC721 with the following extensions:
- ERC721Enumerable
- ERC721URIStorage
- AccessControl
Each agent NFT contains the following metadata:
- Name
- Description
- Input Schema
- Output Schema
- Tags
- Price
- Minimum Validators Required
- Minimum Blocks for Execution
- Agent CID
function safeMint(Agent memory agent, address to) public payable
function updateAgent(uint256 tokenId, Agent memory agent) public
function callAgent(uint256 nftId, bytes calldata inputCidFile, bytes calldata inputData) external payable
function getAgentOutput(uint256 _requestId) external view returns (AgentOutput memory)
- Fixed price of 10 ETH per agent (testnet configuration)
- Custom pricing can be set per agent for execution
To mint a new agent NFT:
- Prepare the agent metadata
- Call
safeMint
with required payment - Agent NFT will be minted with a unique tokenId
To execute an agent:
- Obtain the NFT ID of the desired agent
- Prepare input data and CID file (both are optional, write 0x for empty)
- Call
callAgent
with appropriate parameters and payment - Monitor the request using the returned requestId
- Retrieve results using
getAgentOutput
Agent owners can update their agent's properties using the updateAgent
function.
The contract emits the following events:
RequestSent
: When a new agent execution request is initiatedAgentResult
: When an agent execution is completed
- Role-based access control for administrative functions
- Owner-only agent updates
- Payment validation
- Maximum supply enforcement
The UomiAgent contract implements a sophisticated system for generating and storing all NFT metadata entirely on-chain, including both the metadata JSON and SVG images. Here's a detailed breakdown of how it works:
The contract generates SVG images dynamically using a template-based approach:
function generateImage(uint256 tokenId) internal view returns (string memory) {
Agent memory $ = agents[tokenId];
bytes memory fullSvg = abi.encodePacked(
SVG_PART1, // Base SVG template with styling
tokenId, // NFT identifier
SVG_PART2, // Middle template section
$.name, // Agent name
SVG_PART3 // SVG closing elements
);
return string(
abi.encodePacked(
"data:image/svg+xml;base64,",
Base64.encode(fullSvg)
)
);
}
The tokenURI
function generates a complete metadata structure that's fully compliant with NFT standards:
function tokenURI(uint256 tokenId) public view returns (string memory) {
string memory image = generateImage(tokenId);
Agent memory $ = agents[tokenId];
return string.concat(
"data:application/json;base64,",
Base64.encode(
bytes(
string.concat(
'{"external_url":"https://uomi.ai",',
'"description":"', $.description, '",',
'"name":"', $.name, " #", LibString.toString(tokenId), '",',
// ... additional metadata fields
'"image":"', image, '"}'
)
)
)
);
}
Key metadata components:
- External URL linking to the project
- Agent description and name
- Dynamic attributes array
- Input/output schemas
- Pricing information
- Validation requirements
- Base64 encoded SVG image
The contract includes a utility function for handling dynamic tag arrays:
function _joinTags(string[] memory tags) private pure returns (string memory) {
string memory result;
for (uint i = 0; i < tags.length; i++) {
if (i > 0) {
result = string.concat(result, ',"', tags[i], '"');
} else {
result = string.concat('"', tags[i], '"');
}
}
return result;
}
The metadata implementation employs several gas optimization strategies:
- Use of
string.concat
for efficient string concatenation - Static SVG parts stored as constants
- Minimal storage access through strategic use of memory variables
- Efficient base64 encoding implementation
The contract interacts with two precompiled addresses:
- UOMI_ENGINE:
0x00000000000000000000000000000000756f6D69
- IPFS:
0x00000000000000000000000000000000756f6D69
These precompiles enable:
- Direct on-chain AI agent execution
- Efficient data storage and retrieval
- Integration with the Uomi Network's core functionality
The metadata implementation ensures that each NFT is completely self-contained with all data permanently stored on-chain:
- No external URI dependencies
- No IPFS reliance for core functionality
- Immutable and permanently accessible metadata
- Standard-compliant JSON structure
- Dynamic SVG generation
- Dynamic metadata updates
This project is licensed under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.