town.eth is a peer 2 peer agent simulation where autonomous agents interact with eachother in a circular village economy.
Each agent is:
- an independent Java Spring Boot application instance (representing an independent machine in the real world)
- connected to its own AXL node (p2p messaging)
- identified via an ENS subdomain on Ethereum Sepolia
- capable of reasoning via an LLM (via the LangChain4j library)
- able to send trasactions on the Base Sepolia blockchain
An agent is created based on its application-*.properties file, which is the profile that the instance of the Java application will run with. Examples are application-baker.properties and application-farmer.properties. These files provide information about the agent like its role, the services it provides and its AXL peerId.
When an agent is created, a wallet is generated automatically. The clerk (the wallet address on Ethereum Sepolia that holds the town.eth ENS domain) automatically creates a subdomain following the <role>.town.eth format, based on the role specified in the agents properties file.
for example, agent.role=baker leads to the creation and transfer of the baker.town.eth subdomain to the new agents wallet address. Blockchain interaction happens through the EthereumService and Java wrapper classes for the ENS Registry and Resolver contracts.
The new agent then automatically updates the text records associated with its subdomain. These records hold the peerId and services the agent can provide.
Other agents use ENS lookup through the AgentDiscoveryService to search for villagers with certain roles following the same <role>.town.eth format. For example, a baker that is looking for a farmer to buy wheat from will search the ENS registry for farmer.town.eth. The agent can then see the DiscoveredAgents AXL peerId and services it provides.
The baker can then use this peerId to send a message or service request to the farmer via the AxlClient. The aforementioned agent actions happen through function calls through LangChain4j tools.
Chat messages are normal communication messages between agents sent though AXL nodes of type ChatMessage.
Service requests are special messages of the OrderRequest type that lead to the creation of an Order. This Order is a deterministic sequence of events representing a transaction between two agents. The process follows the following sequence of OrderEvents:
- SERVICE_REQUEST - a new service request was sent from the buyer to the seller
- ORDER_ACCEPTED - the seller accepts the service request. This prompts a
Paymentthrough thePaymentServicefrom the buyer to the seller and a message with the transaction hash on Base Sepolia is sent as proof - PAYMENT_CONFIRMED - the seller confirms the transaction hash and marks the order is paid
- ORDER_COMPLETED - the order is completed
When the program is launched the AgentStartupService is called with the AgentProperties, AxlProperties, EnsService and WalletService injected. It uses those services to setup the agent with its role, peerId, walletAddress and ENS subdomain name.
- After startup the
SimulationEngineis started which creates a virtual thread in the background that calls theAgentDecisionEngineevery 30 second with the latestAgentState. - The
AgentDecisionEnginecalls theBrainAiServicewhere the LLM thinks about what to do next. This can be sending a chat message through theChatService, or creating aOrderRequestthrough theOrderService. - In both cases an
AgentMessagewith aPayloadof the required type gets included in aAxlMessageto be sent to the target peerId through theAxlClient. - The target peer receives the
AxlMessagecontaining theAgentMessagethrough theAxlListener.