This is a hands-on tutorial that walks through building a simple refuel automation using a JS script. Perfect for getting familiar with core API types and execution flows.
While the Execution Layer provides the foundational security and access control for automations, the Orchestration Layer enhances it with scheduling capabilities. For complex automation scenarios that go beyond the standard scheduling API, developers can directly utilize the core execution endpoints. Let's explore this flexibility through an example.
A Simple Cross Chain Refuel BOT
An automation built using Console Automation APIs that helps keep ETH balances topped up across different chains.
Users can subscribe by providing:
A refuelAddress to monitor
minAmount of ETH to maintain
List of chains to watch
The automation checks if the refuelAddress drops below minAmount of ETH on any of the specified chains. If it does, it automatically bridges funds to keep the balances above the minimum threshold
Creating the Automation
To create an automation, the executor must first configure the automation parameters.
Once we have the automation parameters defined, we can create a helper to sign the parameters, as this signature is required for automation creation.
const provider = new providers.JsonRpcProvider(RPC_URL);
const signer = new Wallet(EXECUTOR_PRIVATE_KEY, provider);
async function signAutomationRegistrationMessage(domain, types, message) {
try {
// Create a wallet instance using the private key
const wallet = new ethers.Wallet(privateKey);
// Sign the message according to EIP-712
const signature = await wallet._signTypedData(domain, types, message);
console.log("Signature:", signature);
return signature; // Return the generated signature
} catch (err) {
console.error("Error signing message:", err);
throw err;
}
}
Here, RPC_URL and EXECUTOR_PRIVATE_KEY must be configured with appropriate values.
Once the signature is ready, we can simply call the POST/executor endpoint to create the automation for the executor.
const SVC_BASE_URL = "https://gtw.brahma.fi";
// Function to execute the API call
async function executeApiCall() {
try {
// Generate signature
const signature = await signMessage(
msgParams.domain,
msgParams.types,
msgParams.message
);
// Prepare the data for the POST request
const data = {
config: {
feeInBPS: msgParams.message.feeInBPS,
feeReceiver: msgParams.message.feeReceiver,
feeToken: msgParams.message.feeToken,
limitPerExecution: msgParams.message.limitPerExecution,
inputTokens: msgParams.message.inputTokens,
hopAddresses: msgParams.message.hopAddresses
},
executor: msgParams.message.executor,
signature: signature, // Use the generated signature
chainId: msgParams.domain.chainId,
timestamp: msgParams.message.timestamp,
executorMetadata: {
id: msgParams.message.clientId,
name: "auto-refuel",
logo: "https://smolrefuel.com/logo.png",
metadata: {}
}
};
// Make the POST request using Axios
const response = await axios.post(
`${SVC_BASE_URL}/v1/automations/executor`,
data,
{
headers: {
"Content-Type": "application/json"
}
}
);
console.log("Create Executor response:", response.data);
} catch (error) {
console.error("Error creating Executor response:", error);
}
}
Fetching subscribers of automation
Once the automation is created, Console users will be able to subscribe to the automation from console's Automation Marketplace. The automation executors can fetch a list of all subscribers and their metadata from the API, to perform further operations.
First, the executor's registryID must be fetched in order to fetch its subscribers.
Post fetching, we can also perform further cleanup to filter out the active subscriptions.
const fetchActiveSubscriptions = async (registryID) => {
try {
const response = await Axios.get(
`${SVC_BASE_URL}/v1/automations/executor/${registryID}/subscriptions`
);
const subscriptions = response.data.data;
let activeSubscriptions = [];
for (let subscription of subscriptions) {
// filter our if not currently active
if (subscription.status != CANCELLED_STATUS) {
activeSubscriptions.push(subscription);
}
}
return activeSubscriptions;
} catch (err) {
console.log("err: failed to get subscriptions");
throw "failed to get executor subscriptions";
}
};
Checking if the automation should be executed for a subscriber
The automation only has to be executed, if the refuelAddress has a balance lower than the minAmount threshold on any given chain ID from chains. We define a function to perform a check to see if a target address has a low balance-