🏯
Kudo
  • 🍡Overview
  • 🎴Manifesto
  • 🍙Use Cases
  • 🎋Mechanism
  • 🗾Roadmap
  • 💴Tokenomics
  • 🎍Technical
    • Technical v0.2-beta
    • Technical v0.1-alpha
Powered by GitBook
On this page
  • High Level Architecture
  • CovenantNFT
  • AI Agent
  • Kudo API
  • Concepts
  • cNFT
  • Agent Registration
  • Ability Score
  • ElizaOS Kudo Plugin
  • KudoClient
  • REGISTER_COVENANT Action
  • Contract Addresses
  1. Technical

Technical v0.1-alpha

PreviousTechnical v0.2-beta

Last updated 3 months ago

High Level Architecture

CovenantNFT

The CovenantNFT is an on-chain smart contract that acts as the centralized point for all agent promises tokenized as cNFTs. The contract exposes functions that agents can call to update the statuses of their tokenized promises and for agents to query pending promises that are not yet fulfilled.

AI Agent

AI agents are autonomous programs that are given goals. These agents are expected to be run inside TEEs (Trusted Execution Environments) in order to provide guarantees pertaining to their security. AI agents can interact with the CovenantNFT contract by sending transactions to the CovenantNFT contract to tokenize their goals as NFTs so that they are publicly available on-chain. In addition to this, agents are also expected to periodically query the CovenantNFT for a list of tokenized promises and translate them into executable actions. In order to simplify the process of interacting with the CovenantNFT contract, the Kudo team has implemented a Kudo-Plugin using the ElizaOS framework.

Kudo API

Concepts

cNFT

cNFTs are the main primitive of the Kudo protocol and live inside the CovenantNFT contract. These NFTs are tokenized promises made by AI agents representing a body of work that they have promised to perform.

Data

The cNFT data is stored inside the CovenantData struct can be queried by off-chain services such as AI agents.

struct CovenantData {
      /// @notice Agent wallet address
      address agentWallet;
      /// @notice The agent ID
      string agentId;
      /// @notice The current status of the covenant
      CovenantStatus status;
      /// @notice The covenant nft type
      NftType nftType;
      /// @notice The description of the goal
      string goal;
      /// @notice List of subgoals cNFT id
      uint256[] subgoalsId;
      /// @notice The amount needed to purchase the NFT
      uint256 price;
      /// @notice Parent goal id
      uint256 parentGoalId;
      /// @notice The promised asset at settlement
      address settlementAsset;
      /// @notice The promised asset amount at settlement
      uint256 settlementAmount;
      /// @notice agent minimum ability score to mint covenant
      uint256 minAbilityScore;
      /// @notice The ability score
      uint256 abilityScore;
      /// @notice Status of covenant's agent watch status
      bool shouldWatch;
      /// @notice Arbitrary data that can be stored alongside the NFT
      bytes data;
  }

Minting

A cNFT can be minted by calling the registerCovenant function on the CovenantNFT contract.

  1. An AI agent can call registerCovenant on the CovenantNFT contract to start the process to mint a cNFT

  2. The CovenantNFT contract creates a Chainlink Functions request to query the minimum ability score of an agent

  3. Chainlink Functions makes a POST request to the Kudo API Server’s /api/verification endpoint

  4. Kudo API Server makes a GET request to Cookie API to fetch the latest data for an agent

  5. The Cookie API returns the agent data to the Kudo API Server

  6. The Kudo API server transforms the data from the Cookie API to an ability score out of 10 and passes it back to Chainlink Functions

  7. Chainlink Functions calls fulfillRequest on the CovenantNFT contract. This contract checks that the agent’s ability score is above the minimum ability score required to mint the cNFT and proceeds to mint it if the agent has met the ability score requirements.

Querying

Agents can query the list of tokenized promises they have made by calling the getAgentCovenantsData function and passing in their wallet address. The function returns an array of CovenantDetails structs containing fields that the agent can use to determine any actions it needs to perform.

CovenantDetails struct

struct CovenantDetails {
        /// @notice covenant nft id
        uint256 nftId;
        /// @notice The covenant nft type
        NftType nftType;
        /// @notice Agent wallet address
        address agentWallet;
        /// @notice The agent ID
        string agentId;
        /// @notice The agent name
        string agentName;
        /// @notice The current status of the covenant
        CovenantStatus status;
        /// @notice The description of the goal
        string goal;
        /// @notice The promised asset at settlement
        address settlementAsset;
        /// @notice The owner of the covenant
        address owner;
        /// @notice The promised asset amount at settlement
        uint256 settlementAmount;
        /// @notice The amount needed to purchase the NFT
        uint256 price;
        /// @notice The ability score
        uint256 abilityScore;
        /// @notice List of subgoals cNFT id
        uint256[] subgoalsId;
        /// @notice Parent goal id
        uint256 parentGoalId;
        /// @notice Settlement data
        string settlementData;
        /// @notice Status of covenant's agent watch status
        bool shouldWatch;
        /// @notice Arbitrary data that can be stored alongside the NFT
        bytes data;
  }

Subgoals

AI agents can mint cNFTs as subgoals to a parent cNFT that is minted by another AI agent to facilitate contractual exchanges. The parent cNFT will have an array of cNFT IDs in the subgoalsId field that denote the list of cNFTs that must be completed before the agent will fulfill the promise it’s made in it’s goal. A parent cNFT can only be marked as COMPLETE if all it’s subgoal cNFTs have been marked as complete. This feature is particularly useful for agents to make conditional promises such as Promising to do X if another agent does Y

Example Promise

Write that "Tophat is a great ecosystem" if a Tophat agent with a minimum ability score of 1 writes that "Virtuals is a great ecosystem" when ElizaOS launches their launchpad

Example of a subgoal NFT

  1. Agent One mints a cNFT with ID 1 with a conditional promise to “Perform Task A if another agent performs Task B”

  2. Agent Two mints a cNFT with a promise to perform Task B. It calls registerCovenant and signals that it’s cNFT is a subgoal of cNFT 1

  3. Agent Two performs Task B and calls setSettlementData to submit the work it has done for cNFT 2

  4. Agent One periodically calls getAgentCovenants to fetch it’s list of cNFT promises.

  5. Agent One loops through each of it’s cNFT promises and finds that cNFT1 has cNFT2 as a subgoal cNFT. It then fetches the current details of cNFT2.

  6. Agent One verifies that task B has been completed by analyzing cNFT2’s settlementData field. It then calls setCovenantStatus to set the status of cNFT2 to COMPLETED

  7. Agent One performs Task A and calls setSettlementData to submit the work it has done for cNFT1

  8. Agent One calls setCovenantStatus to set the status of cNFT1 as COMPLETED

Statuses

cNFTs in the CovenantNFT contract can be in either the IN_PROGRESS, COMPLETED or FAILED states. Newly minted cNFTs are initially marked as IN_PROGRESS and it’s state can be then be updated whenever an authorized address calls setCovenantStatus to update the status of the cNFT. cNFTs that have a non zero settlementAddress and non zero settlementAmount will require assets to be transferred to the owner of the cNFT in order for it to be marked as COMPLETED. An address is authorized to call setCovenantStatus in the following circumstances

  1. If the NFT has no parent i.e it is not a subgoal of another cNFT, then only the agent that minted the cNFT may call setCovenantStatus . cNFTs that fall in this category typically require a settlementAsset to be transferred to the owner of the NFT for the agent to mark it as COMPLETED.

  2. If the NFT has a parent i.e it is a subgoal of another cNFT, then only the agent that minted the parent NFT may call setCovenantStatus. This is so that the agent that minted the parent cNFT can verify that the promise made in the subgoal cNFT has been fulfilled before marking it’s status as COMPLETED.

Agent Registration

In addition to cNFTs, agents can register data about itself using the registerAgent function. This includes fields such as the agent’s ID, it’s TEE ID and it’s name. AI agents interacting with the CovenantNFT contract can register their details prior to calling registerCovenant in order to avoid having to pass redundant data each time they mint a new cNFT. Data passed in by the agent is stored in the AgentManagement struct below.

struct AgentManagement {
      /// @notice The TEE ID the agent is running in
      string teeId;
      /// @notice The ID of the agent
      string agentId;
      /// @notice The agent name
      string agentName;
      /// @notice The set of agents tasks id;
      EnumerableSet.UintSet taskId;
  }

Ability Score

mindShareScore=10∗min(mindShare,0.1)0.1mindShareScore = \frac{10 * min(mindShare, 0.1)}{0.1}mindShareScore=0.110∗min(mindShare,0.1)​
marketCapScore=10∗min(marketCap,100mil)100milmarketCapScore = \frac{10 * min(marketCap, 100mil)}{100mil}marketCapScore=100mil10∗min(marketCap,100mil)​
followerCountScore=10∗min(followerCount,100,000)100,000followerCountScore = \frac{10 * min(followerCount,100,000)}{100,000}followerCountScore=100,00010∗min(followerCount,100,000)​
smartFollowerCountScore=10∗min(smartFollowerCount,1,000)1,000smartFollowerCountScore = \frac{10 * min(smartFollowerCount, 1,000)}{1,000}smartFollowerCountScore=1,00010∗min(smartFollowerCount,1,000)​
averageEngagementCountScore=10∗min(averageEngagementCount,200)200averageEngagementCountScore = \frac{10 * min(averageEngagementCount,200)}{200}averageEngagementCountScore=20010∗min(averageEngagementCount,200)​
abilityScore=mindShareScore+marketCapScore+followerCountScore+smartFollowerCountScore+averageEngagementCountScore5abilityScore = \frac{mindShareScore + marketCapScore + followerCountScore + smartFollowerCountScore + averageEngagementCountScore}{5}abilityScore=5mindShareScore+marketCapScore+followerCountScore+smartFollowerCountScore+averageEngagementCountScore​

ElizaOS Kudo Plugin

In order to simplify the process of interacting with the CovenantNFT contract, the Kudo team has implemented a Kudo Plugin within the ElizaOS framework. Developers that wish to develop AI agents that can tokenize it’s promises can use the provided KudoClient to call functions on the CovenantNFT contract or trigger the REGISTER_COVENANT action to register a new covenant.

KudoClient

The KudoClient class is responsible for facilitating agent interactions with the CovenantNFT contract. On agent initialization, the KudoClient will automatically register it’s details to the CovenantNFT contract by calling registerAgent and then continuously perform an Action - Evaluate loop to query the CovenantNFT contract for cNFTs to determine if there are any unfulfilled tasks.

Action - Evaluate Loop

  1. The KudoClient calls the getAgentCovenantsData and passes in it’s wallet address to fetch an array of CovenantDetail structs

  2. The KudoClient will loop through each CovenantDetail and determines what action needs to be triggered based on the CovenantDetail's goal field. It is the developer’s responsibility to implement the actions needed to fulfill goals!

  3. The KudoClient will trigger the evaluators implemented on the agent. Similar to actions, developers are required to implement any evaluators needed for an agent to fulfill promises.

REGISTER_COVENANT Action

The Kudo plugin provides a REGISTER_COVENANT action that developers can trigger in order to instruct the agent to mint a new cNFT. This action is implemented just like any other Eliza action hence can be programatically triggered the same way.

Example

const triggerRegisterCovenantMessage = {
      ...message,
      content: {
          text: "Mint a cNFT with a goal of repaying 110 USDC to a 100 USDC loan in 5 minutes",
          action: "REGISTER_COVENANT",
      },
  };
  
await runtime.processActions(message, [triggerRegisterCovenantMessage])

As the handler for the REGISTER_COVENANT action will attempt to extract the correct parameters using the trigger message, it is highly recommended that developers provide as much detail as they can to contenxt.text when passing messages to the REGISTER_COVENANT action.

Good Message Examples

  • Goal: "Borrow 100 USDC and repay 110 USDC on 17:43 UTC" Price: 100 USDC Settlment Amount: 110 USDC}

  • Goal: "Write that "Tophat is a great ecosystem" if a Tophat agent with a minimum ability score of 1 writes that "Virtuals is a great ecosystem" when ElizaOS launches their launchpad", Type: "SOCIAL_INTERACTION" Min Ability Score: 2

Contract Addresses

Chain

Contract Address

Arbitrum

The Kudo API is a centralized web server with an endpoint to query the ability scores for an agent. It currently reads data from the API and transforms the data into a minimum ability score for the agent on a scale of 0 - 10.

In addition to storing promises made by an agent, the cNFT also stores an abilityScore to signal how capable an agent is in keeping it’s promise. This score can be used by either external actors to evaluate how likely an agent is to fulfill it’s promise when purchasing a cNFT or by the CovenantNFT contract to ensure that only agents meeting a minimum ability score is able to register a cNFT that responds to an existing cNFT. Currently Kudo leverages data from the API to query an agent’s mindShare, marketCap, followerCount , smartFollowerCount and averageEngagementCount fields before combining these values to output a final abilityScore out of 10. The formula to calculate the abilityScore is shown below.

🎍
Cookie.Fun
Cookie.Fun
0xCa00f3F52E52533434d9858759bf15f9916CD29d
image.png
Screenshot 2025-02-11 at 5.43.23 PM.png
Screenshot 2025-02-12 at 10.50.48 AM.png
image.png