EigenLayer AVS API References
Comprehensive guide to working with gRPC endpoints and API references for the Ava Protocol EigenLayer AVS, including authentication and API methods.
To interact with the Ava Protocol, start by making a request to the gRPC endpoint. The protocol is defined in the protobuf directory. A user can use any protobuf client or SDK to make calls to this gRPC endpoint.
For example, using the Node.js @grpc/grpc-js package, you can make the call as shown in this file: https://github.com/AvaProtocol/EigenLayer-AVS/blob/main/examples/example.js. You can review it to learn how to construct a gRPC client if you're not yet familiar with gRPC.
Endpoint#
Ethereum#
aggregator.avaprotocol.org:2206
This run on Ethereum mainnet, you will need to spend actual ETH here to run and test task triggering.
Holesky#
aggregator-holesky.avaprotocol.org:2206
The AVS itself is run on holesky network, but all the target chain for automation is on Sepolia. Therefore, when scheduling task, once triggered, it will be run on Sepolia. Therefore, you don't need Holešky ETH, you only need to keep Sepolia Eth in your wallet or smart wallet.
You can use a few faucet links below to get Sepolia Eth:
- https://cloud.google.com/application/web3/faucet/ethereum/sepolia
- https://sepoliafaucet.com/
- https://sepolia-faucet.pk910.de/
Local dev#
If you're running the AVS locally using our docker compose in https://github.com/AvaProtocol/EigenLayer-AVS, you can connect to this endpoint
127.0.0.1:2206
Authentication#
To start interacting with our protocol for task management, the process consists of two steps:
- Given a wallet address, exchange it for an auth token. This auth token allows you to perform task management for that wallet.
- For any request that requires authentication, include this auth token in request metadata.
1. Exchange an auth token
#
Call the GetKey
method with the following data:
owner
: your wallet addressexpired_at
: the epoch time when your key will expiresignature
: sign a message in the formatkey request for ${wallet_address} expired at ${expired_at}
The response will include a key that can be set in the metadata of subsequent requests. The token will expire at the expired_at
epoch.
You can refer to this example code for guidance on how to generate the signature.
2. Making a gRPC Request#
After obtaining the auth token, for any request that requires authentication, set the authkey: ${your-key-from-above}
header in the request.
Since an account needs to send an auth key generated from the signature above, no one else will be able to view your data, ensuring that your task and parameter data remain private.
API Methods#
GetSmartAccountAddress#
rpc GetSmartAccountAddress(AddressRequest) returns (AddressResp)
This endpoint retrieves the smart wallet address for a specified owner. No authentication is required because this information can also be gathered from on-chain storage.
Request#
- owner (string): The hex address of the account owner whose smart wallet address is being requested.
Response#
- smart_account_address (string): The retrieved smart wallet address for the specified owner.
- nonce (string): The current nonce of the smart wallet
CreateTask#
rpc CreateTask(CreateTaskReq) returns (CreateTaskResp)
This endpoint is used to create a new task with specific actions and triggers.
Request#
- task_type (TaskType): The type of task to create, such as ETHTransferTask or ContractExecutionTask.
- action (TaskAction): The action associated with the task, which can be either an Ethereum transfer (eth_transfer) or a contract execution (contract_execution). The action is complex data structure, refer to [below TaskAction structure] for more document.
- trigger (TaskTrigger): Specifies the conditions under which the task should be executed. Triggers can be based on time, contract query, or an expression. start_at (int64): The epoch time (in seconds) after which the task becomes valid and can be triggered.
- expired_at (int64): The epoch time (in seconds) after which the task is no longer valid and will not be triggered.
- memo (string): An optional field to store arbitrary notes or metadata related to the task.
TaskAction
TaskAction is fundamentally a union type. Depending on task type, the relevant field contains the action data.
-
ETHTransfer: Used when the task is eth transfer
- destination (string): The hex string address of recipient.
- amount (string): the hex string of eth amount.
-
ContractExecution: Used when the task is ContractExecutionTask
- contract_address (string): the target contract address in hex.
- calldata (string): the encoded contract method and its argument to be send to the contract address.
- method (string): optinally - only use for display/format purpose.
- encoded_params (string): optinally - only use for display/format purpose.
TaskTrigger
TaskTrigger is also a union type. Depending on task type, the relevant field contains the trigger data.
-
trigger_type: an enum of TimeCondition, ContractQueryCondition and ExpressionCondition
-
schedule: use when the trigger_type is TimeCondition.
- fixed (array): an list of epoch timestamp when the task can be triggered.
- cron (string): a crontab expression re-present when the task can be triggert
-
contract_query: use when trigger_type is ContractQueryCondition Query a contract, if return value is true, the task is triggered.
- contract_address (string): target contract address in hex format
- callmsg (string): encoded payload in hex format to send to above contract
-
expression: use when trigger_type is ExpressionCondition Perform an expression with operator and function call support by our task engine. If it's evaluated to true, the task is t riggered.
-
expression (string): the raw expression. The language that we use is expr-lang. Beside the built-in primitive support by
expr-lang
, We supported below functions to work with onchain data:- readContractData(contract_address, callmsg): the parameter is similar to contract query with contract_address and callmsg. The queried value is returned.
- latestRoundDataChainlink": chainlinkLatestRoundData
- bigCmp(a, b): compare to Ethereum big int, return 0 if a == b, return 1 if a > b, return -1 if a < b
- toBigint(value): Map to Ethereum ParseBig256
-
Response#
- id (string): The unique identifier of the created task.
ListTasks#
This endpoint returns a list of tasks associated with the account identified by authkey
Request#
No parameters are needed in the request.
Response#
- tasks (repeated TaskItemResp): A list of task items associated with the account.
- id (string): The unique identifier of the task.
- status (TaskStatus): The current status of the task, such as Active, Completed, Failed, etc.
CancelTask#
rpc CancelTask(string) returns (google.protobuf.BoolValue)
This endpoint is used to cancel the task identified by the given ID. The task will be stopped from running. Only tasks in active status can be canceled.
Request#
- id (string) The unique identifier of the task to be deleted.
Response#
BoolValue (google.protobuf.BoolValue): Indicates whether the cancellation was successful (true) or not (false).
DeleteTask#
rpc DeleteTask(string) returns (google.protobuf.BoolValue)
This endpoint deletes a task associated with the given task id
Request#
- id (string) The unique identifier of the task to be deleted.
Response#
BoolValue (google.protobuf.BoolValue): Indicates whether the deletion was successful (true) or not (false).
API clients#
Becuase we use gRPC, so you can leverage the vast ecosystem of gRPC and Protocol Buffer when working with our AVS. Using protocol definition in protobuf
anyone can generate a client use traditional grpc tool, or dynamically generate the client.
Useful links when working with gRPC:
NodeJS Example#
You can refer to this example for a demonstration of how to construct the gRPC client and make call. The step are as below:
-
Generate gRPC client code with your language
grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./static_codegen/ --grpc_out=grpc_js:./static_codegen/ --proto_path=../protobuf avs.proto
This step is useful because it allow you to access the primitive types, enum definion, class etc by importing the JavaScript file in directory
static_codegen
-
Initialize a gRPC client
At minimum, this is enough to establish a dynamic client.
const packageDefinition = protoLoader.loadSync('path/to/avs.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true }) const protoDescriptor = grpc.loadPackageDefinition(packageDefinition) const apProto = protoDescriptor.aggregator const client = new apProto.Aggregator(avsEndpoint, grpc.credentials.createInsecure())
You can always access avs.proto file in https://github.com/AvaProtocol/EigenLayer-AVS/blob/main/protobuf/avs.proto. A common approach is use submodule to manage this file. We plan to eventualy automatically published this file to
npm
for the convenience usage.