The Otomato SDK empowers users to automate crypto-related behaviors. It provides intuitive tools to respond to market dynamics by abstracting complexities.
npm install otomato-sdkFor the first example, set the following environment variables:
API_URL: Should be set tohttps://api.otomato.xyz/api.AUTH_TOKEN: Obtain this by following the Authentication instructions. Alternatively, you can use anAPI_KEYinstead.
Alternatively, you can replace these placeholder values directly in the example code.
This minimal example monitors the ETH price and sends an email notification if it drops below $2500.
import { ACTIONS, Action, TRIGGERS, Trigger, Workflow, CHAINS, getTokenFromSymbol, Edge, apiServices } from 'otomato-sdk';
import dotenv from 'dotenv';
dotenv.config();
async function simpleEthPriceMonitor() {
const API_URL = process.env.API_URL || "https://api.otomato.xyz/api";
const EMAIL_ADDRESS = process.env.EMAIL_ADDRESS || "your-email@example.com"; // Replace with your email or set as ENV var
const AUTH_TOKEN = process.env.AUTH_TOKEN;
const API_KEY = process.env.API_KEY;
if (!AUTH_TOKEN || !API_KEY) {
console.error("Error: AUTH_TOKEN or API_KEY is not set. Please set it as an environment variable or directly in the code.");
return;
}
if (EMAIL_ADDRESS === "your-email@example.com") {
console.warn("Warning: EMAIL_ADDRESS is set to the default. Replace with your email to receive notifications.");
}
apiServices.setUrl(API_URL);
// Use either an API key or an auth token:
// apiServices.setApiKey(process.env.API_KEY);
apiServices.setAuth(AUTH_TOKEN);
const priceTrigger = new Trigger(TRIGGERS.TOKENS.PRICE.PRICE_MOVEMENT_AGAINST_CURRENCY);
priceTrigger.setChainId(CHAINS.BASE); // Using Base network
priceTrigger.setComparisonValue(2500);
priceTrigger.setCondition("lte");
priceTrigger.setParams("currency", "USD");
priceTrigger.setContractAddress(getTokenFromSymbol(CHAINS.BASE, "WETH").contractAddress); // Using WETH on Base as an example
const emailAction = new Action(ACTIONS.NOTIFICATIONS.EMAIL.SEND_EMAIL);
emailAction.setParams("to", EMAIL_ADDRESS);
emailAction.setParams("subject", "ETH Price Alert");
emailAction.setParams("body", `ETH price is now below $2500. Current value: ${priceTrigger.getOutputVariableName('price')}`);
const workflow = new Workflow("Simple ETH Price Monitor", [priceTrigger, emailAction], [new Edge({ source: priceTrigger, target: emailAction })]);
try {
const { success: createSuccess, error: createError } = await workflow.create();
if (!createSuccess) {
console.error(`Error creating workflow: ${createError}`);
return;
}
console.log(`Workflow "${workflow.name}" created with ID: ${workflow.id}. Current state: ${workflow.getState()}`);
const { success: runSuccess, error: runError } = await workflow.run();
if (!runSuccess) {
console.error(`Error running workflow: ${runError}`);
return;
}
console.log(`Workflow "${workflow.name}" is now running. Current state: ${workflow.getState()}`);
} catch (error) {
console.error(`An unexpected error occurred: ${error}`);
}
}
simpleEthPriceMonitor();- Install the SDK:
If you haven't already, install the SDK using npm:
npm install otomato-sdk
- Set Environment Variables (Recommended):
Create a
.envfile in your project's root directory:ReplaceAPI_URL=https://api.otomato.xyz/api AUTH_TOKEN=your-auth-token EMAIL_ADDRESS=your-email@example.comyour-auth-tokenandyour-email@example.comwith your actual credentials. Alternatively, modify these values directly in thesimple_eth_price_monitor.jsfile. - Save the code:
Save the example code as
simple_eth_price_monitor.jsin your project. - Install dependencies:
If using a
.envfile, installdotenv. The SDK itself is already handled by step 1.npm install dotenv
- Run the script:
Execute the script using Node.js:
node simple_eth_price_monitor.js
Before interacting with the Otomato SDK, you need to authenticate. There are two approaches:
API keys are the simplest way to authenticate.
import { apiServices } from 'otomato-sdk';
apiServices.setUrl('https://api.otomato.xyz/api');
apiServices.setApiKey('sk_live_xxxx_...');Set it via environment variable:
API_URL=https://api.otomato.xyz/api
API_KEY=sk_live_xxxx_...
apiServices.setUrl(process.env.API_URL);
apiServices.setApiKey(process.env.API_KEY);Note: If both an API key and an auth token are set, the API key takes priority.
You can also authenticate using an AUTH_TOKEN obtained from the web app or programmatically.
How to get an AUTH_TOKEN:
-
Through the Web App (recommended and fastest way): This is the primary and recommended method. You can obtain a token by visiting
[Your Web App URL Here - e.g., https://app.otomato.xyz/settings/api-keys]. Sign in with your wallet, and you'll typically find the token in your account settings or a dedicated API keys section. -
Programmatically (non-recommended): This method involves generating a login payload, signing it with your wallet, and then exchanging the signature for an
AUTH_TOKEN. This is a secondary method and generally not recommended for most users.import { apiServices, CHAINS } from 'otomato-sdk'; // Ensure CHAINS is imported if used // Example: (Replace with your actual wallet address, access code, owner address, and signing function) async function getAuthToken(walletAddress, accessCode, ownerAddress, signFunction) { try { // Ensure chainId is defined, e.g., CHAINS.ETHEREUM or your specific chain const chainId = CHAINS.ETHEREUM; const loginPayload = await apiServices.generateLoginPayload(walletAddress, chainId, accessCode, ownerAddress); // The signFunction needs to be implemented by you, using your preferred wallet library (ethers.js, web3.js, etc.) // It takes the JSON string of loginPayload and returns a signature. // Example: const signature = await ethersSigner.signMessage(JSON.stringify(loginPayload)); const signature = await signFunction(JSON.stringify(loginPayload)); const { token } = await apiServices.getToken(loginPayload, signature); apiServices.setAuth(token); // Sets token for subsequent SDK use console.log("Authentication successful. AUTH_TOKEN:", token); return token; } catch (error) { console.error("Programmatic authentication failed:", error); throw error; } } // --- How to use getAuthToken (Example Placeholder) --- // This is a conceptual guide. You'll need to integrate with your specific wallet setup. // // import { Wallet } from 'ethers'; // Example using ethers.js // // async function mySignFunction(payloadString) { // const privateKey = "YOUR_PRIVATE_KEY"; // Keep private keys secure! // const wallet = new Wallet(privateKey); // return await wallet.signMessage(payloadString); // } // // const MY_WALLET_ADDRESS = "0xYourWalletAddress"; // const MY_ACCESS_CODE = "YourAccessCode"; // If applicable // const MY_OWNER_WALLET_ADDRESS = "0xOwnerWalletAddress"; // If applicable // // getAuthToken(MY_WALLET_ADDRESS, MY_ACCESS_CODE, MY_OWNER_WALLET_ADDRESS, mySignFunction) // .then(token => { // // Use the token for your Otomato SDK operations // }) // .catch(error => console.error("Failed to get AUTH_TOKEN:", error));
Remember to keep your AUTH_TOKEN secure. Do not commit it directly into version control, especially if hardcoded. Using environment variables (as shown in the first example) is a good practice.
A brief overview of the main components in the Otomato SDK:
A Workflow is the top-level container for your automation logic. It consists of Nodes (Triggers and Actions) connected by Edges, defining the sequence of operations. Key properties include id, name, nodes, edges, and state.
A Node is a fundamental building block in a Workflow, representing either a Trigger or an Action. It has an id, a blockId (type of node), parameters for configuration, and position (for UI).
A Trigger is a special type of Node that starts a Workflow when specific conditions are met (e.g., price movement, new transaction). Methods like setCondition() and setComparisonValue() configure its behavior for polling-based triggers.
An Action is a Node that performs a task within a Workflow (e.g., swap tokens, send a notification, interact with a smart contract). Use setParams() to configure action-specific parameters.
An Edge connects two Nodes (a source and a target), defining the direction of flow and dependencies within a Workflow. It can optionally have a label and a value for conditional branching.
For more details on properties and methods, refer to the API Reference or specific examples.
A Workflow is a collection of Nodes (Triggers and Actions) connected by Edges.
import { Workflow, Trigger, Action, Edge, TRIGGERS, ACTIONS, CHAINS } from 'otomato-sdk';
// Initialize Trigger and Action nodes
const priceTrigger = new Trigger(TRIGGERS.TOKENS.PRICE.PRICE_MOVEMENT_AGAINST_CURRENCY);
priceTrigger.setChainId(CHAINS.MODE);
priceTrigger.setComparisonValue(3000);
priceTrigger.setCondition('lte');
priceTrigger.setParams('currency', 'USD');
priceTrigger.setContractAddress('TOKEN_CONTRACT_ADDRESS');
priceTrigger.setPosition(0, 0);
const swapAction = new Action(ACTIONS.SWAP.ODOS.SWAP);
swapAction.setChainId(CHAINS.MODE);
swapAction.setParams('amount', 'AMOUNT_IN_WEI');
swapAction.setParams('tokenIn', 'TOKEN_IN_CONTRACT_ADDRESS');
swapAction.setParams('tokenOut', 'TOKEN_OUT_CONTRACT_ADDRESS');
swapAction.setPosition(0, 100);
// Create Edges to connect Nodes
const edge = new Edge({ source: priceTrigger, target: swapAction });
// Create Workflow
const workflow = new Workflow('Swap on Price Trigger', [priceTrigger, swapAction], [edge]);// Publish the Workflow
const creationResult = await workflow.create();
if (creationResult.success) {
// Run the Workflow
const runResult = await workflow.run();
if (runResult.success) {
console.log('Workflow is running');
} else {
console.error('Error running workflow:', runResult.error);
}
} else {
console.error('Error creating workflow:', creationResult.error);
}This example demonstrates how to create a workflow that swaps tokens and then deposits them into a lending platform.
import { Workflow, Trigger, Action, Edge, TRIGGERS, ACTIONS, CHAINS, getTokenFromSymbol } from 'otomato-sdk';
// Initialize Trigger
const priceTrigger = new Trigger(TRIGGERS.TOKENS.PRICE.PRICE_MOVEMENT_AGAINST_CURRENCY);
priceTrigger.setChainId(CHAINS.MODE);
priceTrigger.setComparisonValue(3000);
priceTrigger.setCondition('lte');
priceTrigger.setParams('currency', 'USD');
priceTrigger.setContractAddress(getTokenFromSymbol(CHAINS.MODE, 'WETH').contractAddress);
priceTrigger.setPosition(0, 0);
// Initialize Actions
const swapAction = new Action(ACTIONS.SWAP.ODOS.SWAP);
swapAction.setChainId(CHAINS.MODE);
swapAction.setParams('amount', '1000000'); // Amount in token units
swapAction.setParams('tokenIn', getTokenFromSymbol(CHAINS.MODE, 'USDT').contractAddress);
swapAction.setParams('tokenOut', getTokenFromSymbol(CHAINS.MODE, 'WETH').contractAddress);
swapAction.setPosition(0, 100);
const depositAction = new Action(ACTIONS.LENDING.IONIC.DEPOSIT);
depositAction.setChainId(CHAINS.MODE);
depositAction.setParams('tokenToDeposit', getTokenFromSymbol(CHAINS.MODE, 'WETH').contractAddress);
depositAction.setParams('amount', swapAction.getOutputVariableName('amountOut'));
depositAction.setPosition(0, 200);
// Create Edges
const edge1 = new Edge({ source: priceTrigger, target: swapAction });
const edge2 = new Edge({ source: swapAction, target: depositAction });
// Create Workflow
const workflow = new Workflow('Swap and Deposit', [priceTrigger, swapAction, depositAction], [edge1, edge2]);An advanced workflow using conditional branching based on ETH price.
import { Workflow, Trigger, Action, Edge, TRIGGERS, ACTIONS, CHAINS, LOGIC_OPERATORS, ConditionGroup } from 'otomato-sdk';
// Initialize Trigger
const ethPriceTrigger = new Trigger(TRIGGERS.TOKENS.PRICE.PRICE_MOVEMENT_AGAINST_CURRENCY);
ethPriceTrigger.setChainId(CHAINS.MODE);
ethPriceTrigger.setComparisonValue(3000);
ethPriceTrigger.setCondition('lt');
ethPriceTrigger.setParams('currency', 'USD');
ethPriceTrigger.setContractAddress('ETH_CONTRACT_ADDRESS');
ethPriceTrigger.setPosition(0, 0);
// Split Action
const splitAction = new Action(ACTIONS.CORE.SPLIT.SPLIT);
// Conditional Branches
const conditionTrue = new Action(ACTIONS.CORE.CONDITION.IF);
conditionTrue.setParams('logic', LOGIC_OPERATORS.OR);
const conditionGroup = new ConditionGroup(LOGIC_OPERATORS.AND);
conditionGroup.addConditionCheck(ethPriceTrigger.getOutputVariableName('price'), 'lt', 3000);
conditionTrue.setParams('groups', [conditionGroup]);
const slackAction = new Action(ACTIONS.NOTIFICATIONS.SLACK.SEND_MESSAGE);
slackAction.setParams('webhook', 'YOUR_SLACK_WEBHOOK');
slackAction.setParams('message', 'ETH price is below $3000!');
// Create Edges
const edge1 = new Edge({ source: ethPriceTrigger, target: splitAction });
const edge2 = new Edge({ source: splitAction, target: conditionTrue });
const edge3 = new Edge({ source: conditionTrue, target: slackAction, label: 'true', value: 'true' });
// Create Workflow
const workflow = new Workflow('ETH Price Monitoring', [ethPriceTrigger, splitAction, conditionTrue, slackAction], [edge1, edge2, edge3]);This section provides a high-level overview of key classes and their primary methods. For exhaustive details, consult the full API documentation (if available separately) or examine the SDK's source code.
- Methods:
create(): Publishes the workflow to the Otomato platform.run(): Executes the workflow.update(): Updates the workflow.delete(): Deletes the workflow.load(workflowId): Loads a workflow by ID.
- Methods:
setCondition(value): Sets the trigger condition.setComparisonValue(value): Sets the comparison value.setChainId(value): Sets the blockchain network.setContractAddress(value): Sets the contract address.
- Methods:
setParams(key, value): Sets action parameters.setChainId(value): Sets the blockchain network.setContractAddress(value): Sets the contract address.
- Methods:
toJSON(): Serializes the edge.delete(): Deletes the edge.
- Automate Web3 Operations: Build workflows for smart contract interactions, token swaps, notifications, etc.
- Smart Account Ready: Designed for secure automation with Smart Accounts (ERC-4337).
- Modular Design: Use triggers and actions as building blocks for complex strategies.
- Controlled Permissions: Leverage session keys for fine-grained control over asset interactions.
- Extensible: Add custom triggers, actions, and services.
We welcome contributions to enhance the Otomato SDK! Please follow these steps:
- Fork the repository.
- Create a new branch.
- Make your changes, including clear comments and tests (if applicable).
- Submit a pull request for review.
This project is licensed under the MIT License - see the LICENSE file for details.