Add More AVS Types
Adding New AVS Service Types to the App
This guide explains how to add new AVS (Actively Validated Service) service types to the application, based on the existing Squaring Service example. Follow these steps to integrate additional services that interact with the task queue system.
Step 1: Create a New Service Component
Start by creating a new service component similar to the existing Service
component for the Squaring Service example. The new component will be responsible for fetching tasks from the task queue and submitting new tasks. Here's a general structure for a new service:
-
Create a new file in the
components
directory:src/components/NewService.tsx -
Set up the component similar to the Square AVS:
"use client";import TaskQueue from "@/components/TaskQueue/TaskQueue";import { useEffect, useState } from "react";import { TaskQueueEntryProps } from "@/types";import { fetchTasks } from "@/utils/tasks";import SubmitTask from "@/components/AddTask/AddTask";export default function NewService({ address }: { address: string }) {const [taskQueue, setTaskQueue] = useState<TaskQueueEntryProps[]>([]);const getTasks = async () => {const allTasks = await fetchTasks(address);setTaskQueue(allTasks);};useEffect(() => {getTasks();const intervalId = setInterval(() => {getTasks();}, 3000);return () => clearInterval(intervalId);}, []);return (<div><section><h1 className="font-bold text-text-primary text-[26px] mb-4">New Service</h1><div className="grid grid-cols-4 gap-4 pb-[40px] mb-[40px] border-b border-border-primary"><SubmitTask taskQueueAddressCustom={address} /></div></section><section><h1 className="font-bold text-text-primary text-[26px] mb-4">Task Queue</h1><TaskQueue entries={taskQueue} /></section></div>);}
This component should:
- Fetch tasks from the task queue based on the
address
prop. - Display the tasks using the
TaskQueue
component. - Allow new task submissions through the
SubmitTask
component.
Step 2: Implement Task Submission Logic
You need to implement the logic for submitting tasks to the new service. The SubmitTask
component will handle task creation, similar to the Square AVS example.
- Modify the existing
SubmitTask
component if necessary, or create a new component that accepts custom task inputs for your new service:const SubmitTask = ({ taskQueueAddressCustom }: { taskQueueAddressCustom?: string }) => {const [taskInput, setTaskInput] = useState<string>("");const [isSubmitting, setIsSubmitting] = useState<boolean>(false);const appStore = useAppStore();if (!appStore.wallet.address || !appStore.cosmWasmSigningClient) {return null;}const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {e.preventDefault();const taskValue = parseInt(taskInput, 10);const taskQueueClient = new TaskQueueClient(appStore.cosmWasmSigningClient!,appStore.wallet.address,taskQueueAddressCustom || taskQueueAddress);try {setIsSubmitting(true);await taskQueueClient.createTask({description: "New Task",timeout: undefined,payload: { x: taskValue }, // Update payload according to your service needs},"auto",undefined,[{ amount: "1000000", denom: "ulayer" }]);setTaskInput("");} catch (error) {console.error("Error submitting task:", error);} finally {setIsSubmitting(false);}};return (<form onSubmit={handleSubmit}>{/* Form structure for task input */}<inputtype="text"value={taskInput}onChange={(e) => setTaskInput(e.target.value)}disabled={isSubmitting}/><button type="submit" disabled={isSubmitting || taskInput === ""}>{isSubmitting ? "Submitting..." : "Submit"}</button></form>);};
Step 3: Update fetchTasks
Utility
If your new service handles different kinds of tasks, update the fetchTasks
function to correctly handle the data for the new service type. You may need to add custom logic for handling task payloads or results.
- Modify the
fetchTasks
utility:export const fetchTasks = async (taskQueueAddressCustom?: string) => {const cosmWasmClient = await CosmWasmClient.connect(TestnetConfig.rpc_endpoint);const taskQueueQueryClient = new LayerTaskQueue.TaskQueueQueryClient(cosmWasmClient,taskQueueAddressCustom || taskQueueAddress);const tasksCompleted = await taskQueueQueryClient.listCompleted({});const tasksOpen = await taskQueueQueryClient.listOpen({});return [...convertTasksToTaskQueueEntryProps(tasksOpen.tasks),...convertTasksToTaskQueueEntryProps(tasksCompleted.tasks),];};
Step 4: Add the New Service to the UI
To make the new service available in the app, you need to render it in the appropriate part of the UI, such as a route or a section of the dashboard.
-
Add a route for the new service:
- Create a new page in the
app
directory for your service:// src/app/new-service/page.tsximport NewService from "@/components/NewService";const NewServicePage = () => (<div><NewService address="new-service-address" /></div>);export default NewServicePage;
- Create a new page in the
-
Update the navigation to include a link to your new service if necessary.
Connect the frontend to your contracts
Follow the frontend connection guide to learn how to connect the frontend to your contract. You'll need to edit the frontend code to add your task queue address.
Conclusion
By following the steps above, you can easily add new AVS service types to the app. This structure ensures that new services can interact with the task queue in a modular way while maintaining consistency with existing components like the Square AVS service. Make sure to customize task submission and handling logic according to the requirements of each new service type.