otomato-sdk 2.0.63 → 2.0.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -151,7 +151,7 @@ export const TRIGGERS = {
151
151
  "description": "Fetches the balance of an ERC20 and checks it against the specified condition.",
152
152
  "prototype": "erc20Balance",
153
153
  "type": 1,
154
- "method": "function balanceOf(address account) view returns (uint256)",
154
+ "method": "function balanceOf(address account) view returns ((uint256 balance))",
155
155
  "output": {
156
156
  "balance": "float"
157
157
  },
@@ -1555,6 +1555,8 @@ export const TRIGGERS = {
1555
1555
  "output": {
1556
1556
  "sender": "address",
1557
1557
  "recipient": "address",
1558
+ "token0": "erc20",
1559
+ "token1": "erc20",
1558
1560
  "amount0": "int256",
1559
1561
  "amount1": "int256",
1560
1562
  "sqrtPriceX96": "uint160",
@@ -1643,6 +1645,8 @@ export const TRIGGERS = {
1643
1645
  "type": 0,
1644
1646
  "output": {
1645
1647
  "sender": "address",
1648
+ "token0": "erc20",
1649
+ "token1": "erc20",
1646
1650
  "amount0In": "uint256",
1647
1651
  "amount1In": "uint256",
1648
1652
  "amount0Out": "uint256",
@@ -1751,6 +1755,8 @@ export const TRIGGERS = {
1751
1755
  "output": {
1752
1756
  "sender": "address",
1753
1757
  "recipient": "address",
1758
+ "token0": "erc20",
1759
+ "token1": "erc20",
1754
1760
  "amount0": "int256",
1755
1761
  "amount1": "int256",
1756
1762
  "sqrtPriceX96": "uint160",
@@ -1840,6 +1846,8 @@ export const TRIGGERS = {
1840
1846
  "output": {
1841
1847
  "sender": "address",
1842
1848
  "to": "address",
1849
+ "token0": "erc20",
1850
+ "token1": "erc20",
1843
1851
  "amount0In": "uint256",
1844
1852
  "amount1In": "uint256",
1845
1853
  "amount0Out": "uint256",
@@ -1925,7 +1933,7 @@ export const TRIGGERS = {
1925
1933
  "VELODROME": {
1926
1934
  "description": "Monitors swaps on Velodrome pools",
1927
1935
  "chains": [
1928
- 8453
1936
+ 34443
1929
1937
  ],
1930
1938
  "image": "https://otomato-sdk-images.s3.eu-west-1.amazonaws.com/velodrome.jpg",
1931
1939
  "SWAP_IN_CONCENTRATED_POOL": {
@@ -1935,6 +1943,8 @@ export const TRIGGERS = {
1935
1943
  "output": {
1936
1944
  "sender": "address",
1937
1945
  "recipient": "address",
1946
+ "token0": "erc20",
1947
+ "token1": "erc20",
1938
1948
  "amount0": "int256",
1939
1949
  "amount1": "int256",
1940
1950
  "sqrtPriceX96": "uint160",
@@ -1946,7 +1956,7 @@ export const TRIGGERS = {
1946
1956
  {
1947
1957
  "key": "chainId",
1948
1958
  "type": "chainId",
1949
- "description": "The network to monitor swaps on (Base).",
1959
+ "description": "The network to monitor swaps on (MODE).",
1950
1960
  "mandatory": true,
1951
1961
  "category": 0
1952
1962
  },
@@ -2001,15 +2011,15 @@ export const TRIGGERS = {
2001
2011
  "examples": [
2002
2012
  {
2003
2013
  "name": "Monitor all swaps in concentrated pool",
2004
- "description": "Triggers whenever a swap occurs in a Velodrome concentrated liquidity pool (WETH/MODE 0.3%).",
2014
+ "description": "Triggers whenever a swap occurs in a Velodrome concentrated liquidity pool (WETH/USDC 0.05%).",
2005
2015
  "parameters": [
2006
2016
  {
2007
2017
  "key": "chainId",
2008
- "value": 8453
2018
+ "value": 34443
2009
2019
  },
2010
2020
  {
2011
2021
  "key": "contractAddress",
2012
- "value": "0x1E41CDE26b30646bb3DBBea48A63708b00470c1c"
2022
+ "value": "0x3Adf15f77F2911f84b0FE9DbdfF43ef60D40012c"
2013
2023
  }
2014
2024
  ]
2015
2025
  }
@@ -2034,7 +2044,7 @@ export const TRIGGERS = {
2034
2044
  {
2035
2045
  "key": "chainId",
2036
2046
  "type": "chainId",
2037
- "description": "The network to monitor swaps on (Base).",
2047
+ "description": "The network to monitor swaps on (MODE).",
2038
2048
  "mandatory": true,
2039
2049
  "category": 0
2040
2050
  },
@@ -2093,7 +2103,7 @@ export const TRIGGERS = {
2093
2103
  "parameters": [
2094
2104
  {
2095
2105
  "key": "chainId",
2096
- "value": 8453
2106
+ "value": 34443
2097
2107
  },
2098
2108
  {
2099
2109
  "key": "contractAddress",
@@ -2594,7 +2604,9 @@ export const ACTIONS = {
2594
2604
  "tokenIn": "erc20",
2595
2605
  "amountOut": "uint256",
2596
2606
  "tokenOut": "erc20",
2597
- "transactionHash": "string"
2607
+ "transactionHash": "string",
2608
+ "exchangeRate": "float",
2609
+ "logs": "Object"
2598
2610
  },
2599
2611
  "frontendHelpers": {
2600
2612
  "output": {
@@ -4477,7 +4489,9 @@ export const ACTIONS = {
4477
4489
  "tokenIn": "erc20",
4478
4490
  "amountOut": "uint256",
4479
4491
  "tokenOut": "erc20",
4480
- "transactionHash": "string"
4492
+ "transactionHash": "string",
4493
+ "exchangeRate": "float",
4494
+ "logs": "Object"
4481
4495
  },
4482
4496
  "frontendHelpers": {
4483
4497
  "output": {
@@ -1,4 +1,4 @@
1
- export const SDK_VERSION = '2.0.63';
1
+ export const SDK_VERSION = '2.0.64';
2
2
  export function compareVersions(v1, v2) {
3
3
  // Split the version strings into parts
4
4
  const v1Parts = v1.split('.').map(Number);
@@ -1,69 +1,146 @@
1
- // Note: Using 'dagre' for layered DAG layout
2
- import dagre from 'dagre-esm-wrapper';
3
- console.log(dagre);
4
- // or: import * as dagre from 'dagre';
5
- export const xSpacing = 700; // used by dagre as node separation
6
- export const ySpacing = 75;
7
- export const ROOT_X = 400; // we’ll keep references, but Dagre decides actual positions
1
+ export const xSpacing = 500;
2
+ export const ySpacing = 120;
3
+ export const ROOT_X = 400;
8
4
  export const ROOT_Y = 120;
5
+ export function positionWorkflowNodesAvoidOverlap(workflow) {
6
+ // 1) Lay out nodes using existing logic
7
+ positionWorkflowNodes(workflow);
8
+ // 2) Group nodes by 'level' based on vertical position
9
+ const levels = new Map();
10
+ workflow.nodes.forEach((node) => {
11
+ if (node.position) {
12
+ const level = Math.round(node.position.y / ySpacing);
13
+ if (!levels.has(level)) {
14
+ levels.set(level, []);
15
+ }
16
+ levels.get(level).push(node);
17
+ }
18
+ });
19
+ // 3) Resolve horizontal overlaps among *all* nodes in each level
20
+ levels.forEach((levelNodes) => {
21
+ // Sort the nodes in this level by X
22
+ levelNodes.sort((a, b) => { var _a, _b; return ((_a = a.position.x) !== null && _a !== void 0 ? _a : 0) - ((_b = b.position.x) !== null && _b !== void 0 ? _b : 0); });
23
+ // Walk left-to-right, shifting nodes that would collide with the previous one
24
+ for (let i = 1; i < levelNodes.length; i++) {
25
+ const prev = levelNodes[i - 1];
26
+ const current = levelNodes[i];
27
+ // Compute how close they are
28
+ const dx = current.position.x - prev.position.x;
29
+ // If they are too close, shift the current node (and its children) to the right
30
+ if (dx < xSpacing) {
31
+ const shift = xSpacing - dx;
32
+ moveNodeAndChildren(current, shift, workflow.edges);
33
+ }
34
+ }
35
+ });
36
+ // 4) Re-center parents above their children in a bottom-up pass
37
+ centerParentXPositions(workflow);
38
+ }
9
39
  /**
10
- * Dagre-based layout for the “top-down” pass. We’re effectively ignoring the old
11
- * manual code. Instead, we:
12
- * 1) Build a dagre graph
13
- * 2) Add all nodes & edges
14
- * 3) dagre.layout(g)
15
- * 4) Extract positions & write them back to workflow.nodes
40
+ * Lays out the workflow nodes in a rough top-down manner,
41
+ * then positions each node relative to its parent.
16
42
  */
17
43
  export function positionWorkflowNodes(workflow) {
18
- // 1) Create a new directed graph
19
- // doc: https://github.com/dagrejs/dagre
20
- const g = new dagre.graphlib.Graph({ multigraph: false, compound: false });
21
- g.setGraph({
22
- // Some layout options:
23
- rankdir: 'TB', // "top-bottom" layering
24
- nodesep: xSpacing * 0.5, // horizontal spacing
25
- ranksep: ySpacing, // vertical spacing between levels
26
- marginx: 20, // how much margin to leave around the left/right
27
- marginy: 20, // how much margin to leave around the top/bottom
28
- });
29
- g.setDefaultEdgeLabel(() => ({}));
30
- // 2) Add nodes to the graph
31
- // Dagre requires each node have an id and some approximate width/height
32
- workflow.nodes.forEach((node) => {
33
- const nodeId = node.getRef();
34
- // For a typical text-based node, approximate width & height
35
- g.setNode(nodeId, {
36
- label: nodeId,
37
- width: 100,
38
- height: 50
44
+ try {
45
+ // Step 1: Find the starting nodes
46
+ const startingNodes = identityStartingNodes(workflow);
47
+ // Step 2: Place the starting nodes
48
+ let xPosition = ROOT_X;
49
+ startingNodes.forEach((startNode) => {
50
+ startNode.setPosition(xPosition, ROOT_Y);
51
+ xPosition += xSpacing;
39
52
  });
53
+ // Step 3: For all other nodes, position them based on their parent(s)
54
+ const nodesToPosition = workflow.nodes.filter((node) => !startingNodes.includes(node));
55
+ nodesToPosition.forEach((node) => positionNode(node, workflow.edges, xSpacing, ySpacing, workflow));
56
+ }
57
+ catch (e) {
58
+ console.error(e);
59
+ }
60
+ }
61
+ export function positionNode(node, edges, xSpacing, ySpacing, workflow) {
62
+ const parents = getParents(node, edges);
63
+ if (!parents.length)
64
+ return; // Edge case: no parents?
65
+ // Sort children of the first parent by edge labels (true/false) so "true" is left, "false" is right
66
+ const children = getChildren(parents[0], edges).sort((a, b) => {
67
+ var _a, _b;
68
+ const edgeA = edges.find((edge) => edge.source === parents[0] && edge.target === a);
69
+ const edgeB = edges.find((edge) => edge.source === parents[0] && edge.target === b);
70
+ const labelA = (_a = edgeA === null || edgeA === void 0 ? void 0 : edgeA.label) !== null && _a !== void 0 ? _a : "";
71
+ const labelB = (_b = edgeB === null || edgeB === void 0 ? void 0 : edgeB.label) !== null && _b !== void 0 ? _b : "";
72
+ if (labelA === "true" && labelB !== "true")
73
+ return -1;
74
+ if (labelB === "true" && labelA !== "true")
75
+ return 1;
76
+ if (labelA === "false" && labelB !== "false")
77
+ return 1;
78
+ if (labelB === "false" && labelA !== "false")
79
+ return -1;
80
+ return 0;
40
81
  });
41
- // 3) Add edges
42
- // Dagre identifies edges by (sourceId, targetId). We don’t need labels for layout,
43
- // but we can store them if we want. If you rely on “true/false” ordering, we can tweak
44
- // e.g. use edge label as a tie-break. (See advanced docs.)
45
- workflow.edges.forEach((edge) => {
46
- var _a;
47
- const fromId = edge.source.getRef();
48
- const toId = edge.target.getRef();
49
- g.setEdge(fromId, toId, { label: (_a = edge.label) !== null && _a !== void 0 ? _a : '' });
50
- });
51
- // 4) Run Dagre layout
52
- dagre.layout(g);
53
- // 5) Extract positions from Dagre graph and store them back to your Node objects
54
- g.nodes().forEach((nodeId) => {
55
- const dagreNode = g.node(nodeId); // { x, y, width, height, ... }
56
- const nodeObj = workflow.nodes.find((n) => n.getRef() === nodeId);
57
- if (!nodeObj || !dagreNode)
58
- return;
59
- // Store x,y in your node’s position
60
- nodeObj.setPosition(dagreNode.x, dagreNode.y);
82
+ const parentX = parents.reduce((sum, p) => { var _a, _b; return sum + ((_b = (_a = p.position) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : ROOT_X); }, 0) /
83
+ parents.length;
84
+ const parentY = Math.max(...parents.map((p) => { var _a, _b; return (_b = (_a = p.position) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : ROOT_Y; }));
85
+ if (children.length <= 1) {
86
+ node.setPosition(parentX, parentY + ySpacing);
87
+ }
88
+ else {
89
+ // This node’s index among siblings
90
+ const index = children.indexOf(node);
91
+ const offset = index - (children.length - 1) / 2;
92
+ node.setPosition(parentX + offset * xSpacing, parentY + ySpacing);
93
+ }
94
+ }
95
+ /**
96
+ * Repositions each parent node so that its X = average of its children’s X.
97
+ */
98
+ function centerParentXPositions(workflow) {
99
+ var _a, _b;
100
+ // Identify the leaf nodes to start a bottom-up pass
101
+ const queue = identifyLeafNodes(workflow);
102
+ while (queue.length > 0) {
103
+ const child = queue.shift();
104
+ const parents = getParents(child, workflow.edges);
105
+ for (const parent of parents) {
106
+ const children = getChildren(parent, workflow.edges);
107
+ if (children.length) {
108
+ const sumX = children.reduce((acc, c) => { var _a, _b; return acc + ((_b = (_a = c.position) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0); }, 0);
109
+ const avgX = sumX / children.length;
110
+ parent.setPosition(avgX, (_b = (_a = parent.position) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : 0);
111
+ }
112
+ // Push this parent upward in the queue to continue up the chain
113
+ if (!queue.includes(parent)) {
114
+ queue.push(parent);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ /**
120
+ * Recursively shifts a node and all its descendants by `shift` in the x-direction.
121
+ */
122
+ function moveNodeAndChildren(node, shift, edges) {
123
+ node.setPosition(node.position.x + shift, node.position.y);
124
+ edges
125
+ .filter((edge) => edge.source === node)
126
+ .forEach((edge) => {
127
+ moveNodeAndChildren(edge.target, shift, edges);
61
128
  });
62
129
  }
63
130
  /**
64
- * We keep these helper functions the same for external usage (if your code or tests need them),
65
- * but we’re not actively using them in the new Dagre-based layout.
131
+ * A "leaf" node is one that has no children (it’s never the source of an edge).
66
132
  */
133
+ export function identifyLeafNodes(workflow) {
134
+ const sources = new Set(workflow.edges.map((edge) => edge.source.getRef()));
135
+ return workflow.nodes.filter((node) => !sources.has(node.getRef()));
136
+ }
137
+ /**
138
+ * Identify starting nodes (no incoming edges).
139
+ */
140
+ export function identityStartingNodes(workflow) {
141
+ const childRefs = new Set(workflow.edges.map((edge) => edge.target.getRef()));
142
+ return workflow.nodes.filter((node) => !childRefs.has(node.getRef()));
143
+ }
67
144
  export function getChildren(node, edges) {
68
145
  return edges
69
146
  .filter((edge) => edge.source === node)
@@ -84,20 +161,7 @@ export function getEndNodePositions(workflow) {
84
161
  var _a, _b, _c, _d;
85
162
  return ({
86
163
  x: (_b = (_a = node.position) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0,
87
- y: ((_d = (_c = node.position) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0) + ySpacing * 2,
164
+ y: ((_d = (_c = node.position) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0) + ySpacing,
88
165
  });
89
166
  });
90
167
  }
91
- /**
92
- * In Dagre, we no longer do an explicit “identify leaf nodes” or “center parents by average,”
93
- * because the layout library handles that.
94
- * But here’s your old method if something else depends on it.
95
- */
96
- export function identifyLeafNodes(workflow) {
97
- const sources = new Set(workflow.edges.map((edge) => edge.source.getRef()));
98
- return workflow.nodes.filter((node) => !sources.has(node.getRef()));
99
- }
100
- export function identityStartingNodes(workflow) {
101
- const childRefs = new Set(workflow.edges.map((edge) => edge.target.getRef()));
102
- return workflow.nodes.filter((node) => !childRefs.has(node.getRef()));
103
- }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -602,6 +602,8 @@ export declare const TRIGGERS: {
602
602
  output: {
603
603
  sender: string;
604
604
  recipient: string;
605
+ token0: string;
606
+ token1: string;
605
607
  amount0: string;
606
608
  amount1: string;
607
609
  sqrtPriceX96: string;
@@ -646,6 +648,8 @@ export declare const TRIGGERS: {
646
648
  type: number;
647
649
  output: {
648
650
  sender: string;
651
+ token0: string;
652
+ token1: string;
649
653
  amount0In: string;
650
654
  amount1In: string;
651
655
  amount0Out: string;
@@ -696,6 +700,8 @@ export declare const TRIGGERS: {
696
700
  output: {
697
701
  sender: string;
698
702
  recipient: string;
703
+ token0: string;
704
+ token1: string;
699
705
  amount0: string;
700
706
  amount1: string;
701
707
  sqrtPriceX96: string;
@@ -741,6 +747,8 @@ export declare const TRIGGERS: {
741
747
  output: {
742
748
  sender: string;
743
749
  to: string;
750
+ token0: string;
751
+ token1: string;
744
752
  amount0In: string;
745
753
  amount1In: string;
746
754
  amount0Out: string;
@@ -790,6 +798,8 @@ export declare const TRIGGERS: {
790
798
  output: {
791
799
  sender: string;
792
800
  recipient: string;
801
+ token0: string;
802
+ token1: string;
793
803
  amount0: string;
794
804
  amount1: string;
795
805
  sqrtPriceX96: string;
@@ -1137,6 +1147,8 @@ export declare const ACTIONS: {
1137
1147
  amountOut: string;
1138
1148
  tokenOut: string;
1139
1149
  transactionHash: string;
1150
+ exchangeRate: string;
1151
+ logs: string;
1140
1152
  };
1141
1153
  frontendHelpers: {
1142
1154
  output: {
@@ -1956,6 +1968,8 @@ export declare const ACTIONS: {
1956
1968
  amountOut: string;
1957
1969
  tokenOut: string;
1958
1970
  transactionHash: string;
1971
+ exchangeRate: string;
1972
+ logs: string;
1959
1973
  };
1960
1974
  frontendHelpers: {
1961
1975
  output: {
@@ -1,2 +1,2 @@
1
- export declare const SDK_VERSION = "2.0.63";
1
+ export declare const SDK_VERSION = "2.0.64";
2
2
  export declare function compareVersions(v1: string, v2: string): number;
@@ -1,23 +1,25 @@
1
1
  import { Workflow } from '../models/Workflow.js';
2
2
  import { Node } from '../models/Node.js';
3
3
  import { Edge } from '../models/Edge.js';
4
- export declare const xSpacing = 700;
5
- export declare const ySpacing = 75;
4
+ export declare const xSpacing = 500;
5
+ export declare const ySpacing = 120;
6
6
  export declare const ROOT_X = 400;
7
7
  export declare const ROOT_Y = 120;
8
+ export declare function positionWorkflowNodesAvoidOverlap(workflow: Workflow): void;
8
9
  /**
9
- * Dagre-based layout for the “top-down” pass. We’re effectively ignoring the old
10
- * manual code. Instead, we:
11
- * 1) Build a dagre graph
12
- * 2) Add all nodes & edges
13
- * 3) dagre.layout(g)
14
- * 4) Extract positions & write them back to workflow.nodes
10
+ * Lays out the workflow nodes in a rough top-down manner,
11
+ * then positions each node relative to its parent.
15
12
  */
16
13
  export declare function positionWorkflowNodes(workflow: Workflow): void;
14
+ export declare function positionNode(node: Node, edges: Edge[], xSpacing: number, ySpacing: number, workflow: Workflow): void;
17
15
  /**
18
- * We keep these helper functions the same for external usage (if your code or tests need them),
19
- * but we’re not actively using them in the new Dagre-based layout.
16
+ * A "leaf" node is one that has no children (it’s never the source of an edge).
20
17
  */
18
+ export declare function identifyLeafNodes(workflow: Workflow): Node[];
19
+ /**
20
+ * Identify starting nodes (no incoming edges).
21
+ */
22
+ export declare function identityStartingNodes(workflow: Workflow): Node[];
21
23
  export declare function getChildren(node: Node, edges: Edge[]): Node[];
22
24
  export declare function getParents(node: Node, edges: Edge[]): Node[];
23
25
  export declare function getEdges(node: Node, edges: Edge[]): Edge[];
@@ -25,10 +27,3 @@ export declare function getEndNodePositions(workflow: Workflow): {
25
27
  x: number;
26
28
  y: number;
27
29
  }[];
28
- /**
29
- * In Dagre, we no longer do an explicit “identify leaf nodes” or “center parents by average,”
30
- * because the layout library handles that.
31
- * But here’s your old method if something else depends on it.
32
- */
33
- export declare function identifyLeafNodes(workflow: Workflow): Node[];
34
- export declare function identityStartingNodes(workflow: Workflow): Node[];
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "otomato-sdk",
3
- "version": "2.0.63",
3
+ "version": "2.0.65",
4
4
  "description": "An SDK for building and managing automations on Otomato",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/types/src/index.d.ts",
@@ -44,7 +44,6 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "axios": "^1.7.2",
47
- "dagre-esm-wrapper": "1.0.4",
48
47
  "ethers": "^6.13.1",
49
48
  "jsonwebtoken": "^9.0.2",
50
49
  "mustache": "^4.2.0"