Skip to content

Otomatorg/otomato-sdk

Repository files navigation

Otomato SDK

The Otomato SDK empowers users to automate crypto-related behaviors. It provides intuitive tools to respond to market dynamics by abstracting complexities.

Table of Contents

Getting Started

Installation

npm install otomato-sdk

Setting Up Environment Variables

For the first example, set the following environment variables:

  • API_URL: Should be set to https://api.otomato.xyz/api.
  • AUTH_TOKEN: Obtain this by following the Authentication instructions. Alternatively, you can use an API_KEY instead.

Alternatively, you can replace these placeholder values directly in the example code.

Simple ETH Price Monitor Example

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();

Running the First Example

  1. Install the SDK: If you haven't already, install the SDK using npm:
    npm install otomato-sdk
  2. Set Environment Variables (Recommended): Create a .env file in your project's root directory:
    API_URL=https://api.otomato.xyz/api
    AUTH_TOKEN=your-auth-token
    EMAIL_ADDRESS=your-email@example.com
    
    Replace your-auth-token and your-email@example.com with your actual credentials. Alternatively, modify these values directly in the simple_eth_price_monitor.js file.
  3. Save the code: Save the example code as simple_eth_price_monitor.js in your project.
  4. Install dependencies: If using a .env file, install dotenv. The SDK itself is already handled by step 1.
    npm install dotenv
  5. Run the script: Execute the script using Node.js:
    node simple_eth_price_monitor.js

Authentication

Before interacting with the Otomato SDK, you need to authenticate. There are two approaches:

Option 1: API Key (Recommended)

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.

Option 2: Auth Token

You can also authenticate using an AUTH_TOKEN obtained from the web app or programmatically.

How to get an AUTH_TOKEN:

  1. 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.

  2. 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.

Going Further

Core Concepts

A brief overview of the main components in the Otomato SDK:

Workflow

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.

Node

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).

Trigger

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.

Action

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.

Edge

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.

Examples

Creating a workflow

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]);

Running a Workflow

// 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);
}

Swap and Deposit Workflow

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]);

ETH Price Monitoring with Split Conditions

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]);

API Reference

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.

Workflow Class

  • 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.

Trigger Class

  • 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.

Action Class

  • Methods:
    • setParams(key, value): Sets action parameters.
    • setChainId(value): Sets the blockchain network.
    • setContractAddress(value): Sets the contract address.

Edge Class

  • Methods:
    • toJSON(): Serializes the edge.
    • delete(): Deletes the edge.

Features

  • 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.

Contributing

We welcome contributions to enhance the Otomato SDK! Please follow these steps:

  1. Fork the repository.
  2. Create a new branch.
  3. Make your changes, including clear comments and tests (if applicable).
  4. Submit a pull request for review.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A TypeScript SDK for creating and managing agents using Otomato

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors