otomato-sdk 1.3.2 → 1.3.5
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.
- package/README.md +2 -2
- package/dist/examples/create-action.js +6 -6
- package/dist/examples/create-trigger-list.js +5 -10
- package/dist/examples/create-trigger.js +21 -7
- package/dist/examples/create-workflow.js +33 -23
- package/dist/examples/load-workflow.js +1 -1
- package/dist/examples/login.js +32 -0
- package/dist/src/constants/Blocks.js +4 -4
- package/dist/src/constants/chains.js +1 -1
- package/dist/src/constants/tokens.js +13 -3
- package/dist/src/index.js +1 -0
- package/dist/src/models/Action.js +72 -0
- package/dist/src/models/Node.js +46 -57
- package/dist/src/models/Trigger.js +80 -4
- package/dist/src/models/Workflow.js +40 -9
- package/dist/src/services/ApiService.js +27 -5
- package/dist/src/utils/helpers.js +19 -0
- package/dist/src/utils/typeValidator.js +34 -8
- package/dist/test/action.spec.js +80 -11
- package/dist/test/automation.spec.js +9 -8
- package/dist/test/helpers.spec.js +23 -0
- package/dist/test/node.spec.js +13 -19
- package/dist/test/trigger.spec.js +92 -19
- package/dist/types/examples/login.d.ts +1 -0
- package/dist/types/src/constants/tokens.d.ts +2 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/models/Action.d.ts +6 -1
- package/dist/types/src/models/Node.d.ts +13 -2
- package/dist/types/src/models/Trigger.d.ts +8 -2
- package/dist/types/src/models/Workflow.d.ts +14 -1
- package/dist/types/src/services/ApiService.d.ts +6 -1
- package/dist/types/src/utils/helpers.d.ts +2 -0
- package/dist/types/src/utils/typeValidator.d.ts +1 -0
- package/dist/types/test/helpers.spec.d.ts +1 -0
- package/examples/create-action.ts +6 -6
- package/examples/create-trigger-list.ts +5 -10
- package/examples/create-trigger.ts +14 -7
- package/examples/create-workflow.ts +43 -25
- package/examples/load-workflow.ts +1 -1
- package/examples/login.ts +27 -0
- package/package.json +4 -2
- package/src/constants/Blocks.ts +4 -4
- package/src/constants/chains.ts +1 -1
- package/src/constants/tokens.ts +18 -4
- package/src/index.ts +1 -0
- package/src/models/Action.ts +77 -3
- package/src/models/Node.ts +54 -65
- package/src/models/Trigger.ts +84 -6
- package/src/models/Workflow.ts +37 -10
- package/src/services/ApiService.ts +24 -5
- package/src/utils/helpers.ts +9 -0
- package/src/utils/typeValidator.ts +28 -11
- package/test/action.spec.ts +75 -11
- package/test/automation.spec.ts +9 -8
- package/test/helpers.spec.ts +16 -0
- package/test/node.spec.ts +17 -23
- package/test/trigger.spec.ts +89 -19
package/src/constants/tokens.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const TOKENS: Tokens = {
|
|
|
18
18
|
decimals: 6
|
|
19
19
|
},
|
|
20
20
|
],
|
|
21
|
-
|
|
21
|
+
34443: [
|
|
22
22
|
{
|
|
23
23
|
contractAddress: "0x0000000000000000000000000000000000000000",
|
|
24
24
|
name: "ETH",
|
|
@@ -101,7 +101,7 @@ export const NFTS: NFTs = {
|
|
|
101
101
|
contractAddress: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
|
|
102
102
|
name: "BoredApeYachtClub"
|
|
103
103
|
},
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
{
|
|
106
106
|
contractAddress: "0xbd3531da5cf5857e7cfaa92426877b022e612cf8",
|
|
107
107
|
name: "Pudgy Penguins"
|
|
@@ -116,7 +116,7 @@ export const NFTS: NFTs = {
|
|
|
116
116
|
},
|
|
117
117
|
|
|
118
118
|
],
|
|
119
|
-
|
|
119
|
+
34443: [
|
|
120
120
|
{
|
|
121
121
|
contractAddress: "0x2ad86eeec513ac16804bb05310214c3fd496835b",
|
|
122
122
|
name: "Space id"
|
|
@@ -124,7 +124,21 @@ export const NFTS: NFTs = {
|
|
|
124
124
|
]
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
-
export function getToken(chain: number,
|
|
127
|
+
export function getToken(chain: number, contractAddress: string): Token {
|
|
128
|
+
if (!(chain in TOKENS)) {
|
|
129
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const token = TOKENS[chain].find(token => token.contractAddress.toLowerCase() === contractAddress.toLowerCase());
|
|
133
|
+
|
|
134
|
+
if (!token) {
|
|
135
|
+
throw new Error(`Token with contract address ${contractAddress} not found on chain ${chain}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return token;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function getTokenFromSymbol(chain: number, symbol: string): Token {
|
|
128
142
|
if (!(chain in TOKENS)) {
|
|
129
143
|
throw new Error(`Unsupported chain: ${chain}`);
|
|
130
144
|
}
|
package/src/index.ts
CHANGED
package/src/models/Action.ts
CHANGED
|
@@ -1,8 +1,82 @@
|
|
|
1
1
|
import { Parameter } from './Parameter.js';
|
|
2
|
-
import { Node, Position } from './Node.js';
|
|
2
|
+
import { Node, ParentInfo, Position } from './Node.js';
|
|
3
|
+
import { ACTIONS } from '../constants/Blocks.js';
|
|
4
|
+
import { ethers } from 'ethers';
|
|
5
|
+
import { typeIsNumber } from '../utils/typeValidator.js';
|
|
3
6
|
|
|
4
7
|
export class Action extends Node {
|
|
5
|
-
constructor(action: { blockId: number; name: string; description: string; parameters: Parameter[], image: string, ref?: string, position?: Position }) {
|
|
8
|
+
constructor(action: { blockId: number; name: string; description: string; parameters: Parameter[], image: string, ref?: string, position?: Position, parentInfo?: ParentInfo }) {
|
|
6
9
|
super({ ...action, class: 'action' });
|
|
7
10
|
}
|
|
8
|
-
|
|
11
|
+
|
|
12
|
+
getStaticParameters(): null {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static async fromJSON(json: { [key: string]: any }): Promise<Action> {
|
|
17
|
+
const enriched = findActionByBlockId(json.blockId);
|
|
18
|
+
|
|
19
|
+
const action = new Action({
|
|
20
|
+
...enriched.block,
|
|
21
|
+
ref: json.ref,
|
|
22
|
+
position: json.position,
|
|
23
|
+
parentInfo: enriched.parentInfo
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
for (const [key, value] of Object.entries(json.parameters)) {
|
|
27
|
+
switch (key) {
|
|
28
|
+
case 'chainId':
|
|
29
|
+
action.setChainId(value as number);
|
|
30
|
+
break;
|
|
31
|
+
case 'contractAddress':
|
|
32
|
+
action.setContractAddress(value as string);
|
|
33
|
+
break;
|
|
34
|
+
case 'abi':
|
|
35
|
+
const abiParameters = (value as { parameters: { [key: string]: any } }).parameters;
|
|
36
|
+
for (const abiKey in abiParameters) {
|
|
37
|
+
const enrichedParameter = enriched.block.parameters.find((param: Parameter) => param.key === `abiParams.${abiKey}`);
|
|
38
|
+
const paramType = enrichedParameter ? enrichedParameter.type : null;
|
|
39
|
+
|
|
40
|
+
if (!abiParameters[abiKey] || !paramType)
|
|
41
|
+
continue;
|
|
42
|
+
|
|
43
|
+
if (typeIsNumber(paramType) && typeof abiParameters[abiKey] === 'string' && abiParameters[abiKey].endsWith('n')) {
|
|
44
|
+
action.setParams(abiKey, BigInt(abiParameters[abiKey].slice(0, -1)));
|
|
45
|
+
} else {
|
|
46
|
+
action.setParams(abiKey, abiParameters[abiKey]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
case 'interval':
|
|
51
|
+
// ignore
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
action.setParams(key, value);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
action.setId(json.id);
|
|
60
|
+
return action;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const findActionByBlockId = (blockId: number): { parentInfo: ParentInfo; block: any } => {
|
|
65
|
+
for (const category in ACTIONS) {
|
|
66
|
+
for (const service in (ACTIONS as any)[category]) {
|
|
67
|
+
for (const actionKey in (ACTIONS as any)[category][service]) {
|
|
68
|
+
if ((ACTIONS as any)[category][service][actionKey].blockId === blockId) {
|
|
69
|
+
return {
|
|
70
|
+
parentInfo: {
|
|
71
|
+
name: service,
|
|
72
|
+
description: (ACTIONS as any)[category][service].description,
|
|
73
|
+
image: (ACTIONS as any)[category][service].image,
|
|
74
|
+
},
|
|
75
|
+
block: (ACTIONS as any)[category][service][actionKey],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`Action with id ${blockId} not found`);
|
|
82
|
+
};
|
package/src/models/Node.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
// Assuming you have the ACTIONS constant defined as you provided
|
|
2
|
-
|
|
3
1
|
import { Parameter } from './Parameter.js';
|
|
4
2
|
import { validateType } from '../utils/typeValidator.js';
|
|
5
3
|
import { ACTIONS, TRIGGERS } from '../constants/Blocks.js';
|
|
4
|
+
import { Trigger } from './Trigger.js';
|
|
5
|
+
import { Action } from './Action.js';
|
|
6
6
|
|
|
7
7
|
export interface Position {
|
|
8
8
|
x: number;
|
|
9
9
|
y: number;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export interface ParentInfo {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
image: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
let nodeCounter = 0;
|
|
13
19
|
const generatedRefs = new Set<string>();
|
|
14
20
|
|
|
15
|
-
export class Node {
|
|
21
|
+
export abstract class Node {
|
|
16
22
|
id: string | null = null;
|
|
17
23
|
blockId: number;
|
|
18
24
|
name: string;
|
|
@@ -23,8 +29,9 @@ export class Node {
|
|
|
23
29
|
ref: string;
|
|
24
30
|
class: string;
|
|
25
31
|
image: string;
|
|
32
|
+
parentInfo?: ParentInfo;
|
|
26
33
|
|
|
27
|
-
constructor(node: { blockId: number; name: string; description: string; parameters: Parameter[], ref?: string, position?: Position, class: string; image: string }) {
|
|
34
|
+
constructor(node: { blockId: number; name: string; description: string; parameters: Parameter[], ref?: string, position?: Position, class: string; image: string; parentInfo?: ParentInfo }) {
|
|
28
35
|
this.id = null;
|
|
29
36
|
this.blockId = node.blockId;
|
|
30
37
|
this.name = node.name;
|
|
@@ -33,7 +40,8 @@ export class Node {
|
|
|
33
40
|
this.parameters = {};
|
|
34
41
|
this.keyMap = {};
|
|
35
42
|
this.class = node.class;
|
|
36
|
-
|
|
43
|
+
this.parentInfo = node.parentInfo;
|
|
44
|
+
|
|
37
45
|
if (node.ref) {
|
|
38
46
|
this.ref = node.ref;
|
|
39
47
|
} else {
|
|
@@ -80,6 +88,10 @@ export class Node {
|
|
|
80
88
|
return this.ref;
|
|
81
89
|
}
|
|
82
90
|
|
|
91
|
+
getParentInfo(): ParentInfo | undefined {
|
|
92
|
+
return this.parentInfo;
|
|
93
|
+
}
|
|
94
|
+
|
|
83
95
|
protected setParameter(key: string, value: any): void {
|
|
84
96
|
if (key in this.parameters) {
|
|
85
97
|
const param = this.parameters[key];
|
|
@@ -116,83 +128,60 @@ export class Node {
|
|
|
116
128
|
}, {} as { [key: string]: any });
|
|
117
129
|
}
|
|
118
130
|
|
|
131
|
+
getStaticParameters(): { [key: string]: any } | null {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
119
135
|
toJSON(): { [key: string]: any } {
|
|
136
|
+
const serializeBigInt = (key: string, value: any) => {
|
|
137
|
+
if (typeof value === 'bigint') {
|
|
138
|
+
return value.toString() + 'n';
|
|
139
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
140
|
+
// Recursively call serializeBigInt for nested objects
|
|
141
|
+
return Object.entries(value).reduce((acc, [k, v]) => {
|
|
142
|
+
acc[k] = serializeBigInt(k, v);
|
|
143
|
+
return acc;
|
|
144
|
+
}, {} as { [key: string]: any });
|
|
145
|
+
} else {
|
|
146
|
+
return value;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const staticParameters = this.getStaticParameters() || {};
|
|
151
|
+
|
|
120
152
|
const json: { [key: string]: any } = {
|
|
121
153
|
id: this.id,
|
|
122
154
|
ref: this.ref,
|
|
123
155
|
blockId: this.blockId,
|
|
124
156
|
type: this.class,
|
|
125
|
-
parameters:
|
|
157
|
+
parameters: {
|
|
158
|
+
...this.getParameters(),
|
|
159
|
+
...staticParameters,
|
|
160
|
+
},
|
|
126
161
|
};
|
|
127
162
|
if (this.position) {
|
|
128
163
|
json.position = this.position;
|
|
129
164
|
}
|
|
130
|
-
return json;
|
|
165
|
+
return JSON.parse(JSON.stringify(json, serializeBigInt));
|
|
131
166
|
}
|
|
132
167
|
|
|
133
168
|
private getSimplifiedKey(key: string): string {
|
|
134
169
|
return key.replace(/[.\[\]]/g, '_');
|
|
135
170
|
}
|
|
136
171
|
|
|
137
|
-
static fromJSON(json: { [key: string]: any }): Node {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (!enriched)
|
|
143
|
-
enriched = {name: "Unknown", description: "Unknown", image: "Unknown"}
|
|
144
|
-
|
|
145
|
-
const parameters = Object.keys(json.parameters).map(key => ({
|
|
146
|
-
key,
|
|
147
|
-
type: typeof json.parameters[key], // Assuming type can be derived from the value's type
|
|
148
|
-
description: '', // Add appropriate description if needed
|
|
149
|
-
value: json.parameters[key]
|
|
150
|
-
}));
|
|
151
|
-
const node = new Node({
|
|
152
|
-
blockId: json.blockId,
|
|
153
|
-
name: enriched.name,
|
|
154
|
-
description: enriched.description,
|
|
155
|
-
image: enriched.image,
|
|
156
|
-
parameters,
|
|
157
|
-
ref: json.ref,
|
|
158
|
-
position: json.position,
|
|
159
|
-
class: json.type
|
|
160
|
-
});
|
|
161
|
-
node.setId(json.id);
|
|
162
|
-
return node;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const findActionByBlockId = (blockId: number): { name: string; description: string; image: string } | null => {
|
|
167
|
-
for (const category in ACTIONS) {
|
|
168
|
-
for (const service in (ACTIONS as any)[category]) {
|
|
169
|
-
for (const actionKey in (ACTIONS as any)[category][service]) {
|
|
170
|
-
if ((ACTIONS as any)[category][service][actionKey].blockId === blockId) {
|
|
171
|
-
return {
|
|
172
|
-
name: (ACTIONS as any)[category][service][actionKey].name,
|
|
173
|
-
description: (ACTIONS as any)[category][service][actionKey].description,
|
|
174
|
-
image: (ACTIONS as any)[category][service][actionKey].image,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
172
|
+
static async fromJSON(json: { [key: string]: any }): Promise<Node> {
|
|
173
|
+
switch (json.type) {
|
|
174
|
+
case 'trigger': {
|
|
175
|
+
const { Trigger } = await import('./Trigger.js');
|
|
176
|
+
return Trigger.fromJSON(json);
|
|
177
177
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const findTriggerByBlockId = (blockId: number): { name: string; description: string; image: string } | null => {
|
|
184
|
-
for (const category in TRIGGERS) {
|
|
185
|
-
for (const service in (TRIGGERS as any)[category]) {
|
|
186
|
-
for (const triggerKey in (TRIGGERS as any)[category][service]) {
|
|
187
|
-
if ((TRIGGERS as any)[category][service][triggerKey].blockId === blockId) {
|
|
188
|
-
return {
|
|
189
|
-
name: (TRIGGERS as any)[category][service][triggerKey].name,
|
|
190
|
-
description: (TRIGGERS as any)[category][service][triggerKey].description,
|
|
191
|
-
image: (TRIGGERS as any)[category][service][triggerKey].image,
|
|
192
|
-
};
|
|
193
|
-
}
|
|
178
|
+
case 'action': {
|
|
179
|
+
const { Action } = await import('./Action.js');
|
|
180
|
+
return Action.fromJSON(json);
|
|
194
181
|
}
|
|
182
|
+
default:
|
|
183
|
+
throw new Error(`Unsupported type: ${json.type}`);
|
|
195
184
|
}
|
|
196
185
|
}
|
|
197
|
-
|
|
198
|
-
}
|
|
186
|
+
|
|
187
|
+
}
|
package/src/models/Trigger.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { Node, ParentInfo, Position } from './Node.js';
|
|
1
2
|
import { Parameter } from './Parameter.js';
|
|
2
|
-
import {
|
|
3
|
+
import { TRIGGERS } from '../constants/Blocks.js';
|
|
4
|
+
import { ethers } from 'ethers';
|
|
5
|
+
import { typeIsNumber } from '../utils/typeValidator.js';
|
|
3
6
|
|
|
4
7
|
export class Trigger extends Node {
|
|
5
8
|
type: number;
|
|
6
9
|
|
|
7
|
-
constructor(trigger: { blockId: number; name: string; description: string; type: number; parameters: Parameter[], image: string, ref?: string, position?: Position }) {
|
|
10
|
+
constructor(trigger: { blockId: number; name: string; description: string; type: number; parameters: Parameter[], image: string, ref?: string, position?: Position, parentInfo?: ParentInfo }) {
|
|
8
11
|
super({ ...trigger, class: 'trigger' });
|
|
9
12
|
this.type = trigger.type;
|
|
10
13
|
}
|
|
@@ -27,10 +30,85 @@ export class Trigger extends Node {
|
|
|
27
30
|
this.setParameter('comparisonValue', value);
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
if (this.notAPollingTrigger()) {
|
|
32
|
-
|
|
33
|
+
getStaticParameters(): { interval: number } | null {
|
|
34
|
+
if (!this.notAPollingTrigger()) {
|
|
35
|
+
return { interval: 5000 };
|
|
33
36
|
}
|
|
34
|
-
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static async fromJSON(json: { [key: string]: any }): Promise<Trigger> {
|
|
41
|
+
const enriched = findTriggerByBlockId(json.blockId);
|
|
42
|
+
|
|
43
|
+
const trigger = new Trigger({
|
|
44
|
+
...enriched.block,
|
|
45
|
+
ref: json.ref,
|
|
46
|
+
position: json.position,
|
|
47
|
+
parentInfo: enriched.parentInfo
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
for (const [key, value] of Object.entries(json.parameters)) {
|
|
51
|
+
switch (key) {
|
|
52
|
+
case 'chainId':
|
|
53
|
+
trigger.setChainId(value as number);
|
|
54
|
+
break;
|
|
55
|
+
case 'contractAddress':
|
|
56
|
+
trigger.setContractAddress(value as string);
|
|
57
|
+
break;
|
|
58
|
+
case 'condition':
|
|
59
|
+
trigger.setCondition(value as string);
|
|
60
|
+
break;
|
|
61
|
+
case 'comparisonValue':
|
|
62
|
+
trigger.setComparisonValue(value as number);
|
|
63
|
+
break;
|
|
64
|
+
case 'abi':
|
|
65
|
+
const abiParameters = (value as { parameters: { [key: string]: any } }).parameters;
|
|
66
|
+
for (const abiKey in abiParameters) {
|
|
67
|
+
const enrichedParameter = enriched.block.parameters.find((param: Parameter) => param.key === `abiParams.${abiKey}`);
|
|
68
|
+
const paramType = enrichedParameter ? enrichedParameter.type : null;
|
|
69
|
+
|
|
70
|
+
if (!abiParameters[abiKey] || !paramType)
|
|
71
|
+
continue;
|
|
72
|
+
|
|
73
|
+
if (typeIsNumber(paramType) && typeof abiParameters[abiKey] === 'string' && abiParameters[abiKey].endsWith('n')) {
|
|
74
|
+
trigger.setParams(abiKey, BigInt(abiParameters[abiKey].slice(0, -1)));
|
|
75
|
+
} else {
|
|
76
|
+
trigger.setParams(abiKey, abiParameters[abiKey]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
case 'interval':
|
|
82
|
+
// ignore
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
trigger.setParams(key, value);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
trigger.setId(json.id);
|
|
91
|
+
return trigger;
|
|
35
92
|
}
|
|
36
93
|
}
|
|
94
|
+
|
|
95
|
+
// Assuming findTriggerByBlockId function is defined as mentioned
|
|
96
|
+
const findTriggerByBlockId = (blockId: number): { parentInfo: ParentInfo; block: any } => {
|
|
97
|
+
for (const category in TRIGGERS) {
|
|
98
|
+
for (const service in (TRIGGERS as any)[category]) {
|
|
99
|
+
for (const triggerKey in (TRIGGERS as any)[category][service]) {
|
|
100
|
+
if ((TRIGGERS as any)[category][service][triggerKey].blockId === blockId) {
|
|
101
|
+
return {
|
|
102
|
+
parentInfo: {
|
|
103
|
+
name: service,
|
|
104
|
+
description: (TRIGGERS as any)[category][service].description,
|
|
105
|
+
image: (TRIGGERS as any)[category][service].image,
|
|
106
|
+
},
|
|
107
|
+
block: (TRIGGERS as any)[category][service][triggerKey],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
throw new Error(`Trigger with id ${blockId} not found`);
|
|
114
|
+
};
|
package/src/models/Workflow.ts
CHANGED
|
@@ -44,18 +44,27 @@ export class Workflow {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
async create() {
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
try {
|
|
48
|
+
const response = await apiServices.post('/workflows', this.toJSON());
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
if (response.status === 201) {
|
|
51
|
+
this.id = response.data.id; // Assign the returned ID to the workflow instance
|
|
52
|
+
|
|
53
|
+
// Assign IDs to the nodes based on the response
|
|
54
|
+
response.data.nodes.forEach((nodeResponse: any) => {
|
|
55
|
+
const node = this.nodes.find(n => n.getRef() === nodeResponse.ref);
|
|
56
|
+
if (node) {
|
|
57
|
+
node.setId(nodeResponse.id);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
return { success: true };
|
|
62
|
+
} else {
|
|
63
|
+
return { success: false, error: response.data?.error || 'Unknown error' };
|
|
64
|
+
}
|
|
65
|
+
} catch (error: any) {
|
|
66
|
+
return { success: false, error: error.message || 'Unknown error' };
|
|
67
|
+
}
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
async load(workflowId: string): Promise<Workflow> {
|
|
@@ -66,4 +75,22 @@ export class Workflow {
|
|
|
66
75
|
this.edges = response.edges.map((edgeData: any) => Edge.fromJSON(edgeData));
|
|
67
76
|
return this;
|
|
68
77
|
}
|
|
78
|
+
|
|
79
|
+
async run() {
|
|
80
|
+
if (!this.id) {
|
|
81
|
+
throw new Error('The workflow needs to be published first');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const response = await apiServices.post(`/workflows/${this.id}/run`, this.toJSON());
|
|
86
|
+
|
|
87
|
+
if (response.status === 204) {
|
|
88
|
+
return { success: true };
|
|
89
|
+
} else {
|
|
90
|
+
return { success: false, error: response.data?.error || 'Unknown error' };
|
|
91
|
+
}
|
|
92
|
+
} catch (error: any) {
|
|
93
|
+
return { success: false, error: error.message || 'Unknown error' };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
69
96
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// networkService.ts
|
|
2
1
|
import axios from 'axios';
|
|
3
2
|
|
|
4
3
|
const API_CONFIG = {
|
|
@@ -21,10 +20,8 @@ class ApiServices {
|
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
async post(url: string, data: any) {
|
|
24
|
-
console.log(JSON.stringify(data));
|
|
25
23
|
const headers = this.auth ? { 'Authorization': this.auth } : {};
|
|
26
|
-
|
|
27
|
-
return response.data;
|
|
24
|
+
return await axiosInstance.post(url, data, { headers });
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
async get(url: string) {
|
|
@@ -33,7 +30,29 @@ class ApiServices {
|
|
|
33
30
|
return response.data;
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
async generateLoginPayload(address: string, chainId: number) {
|
|
34
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
35
|
+
const response = await axiosInstance.post('/auth/generate-payload', { address, chainId }, { headers });
|
|
36
|
+
return response.data;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async getToken(loginPayload: any, signature: string) {
|
|
40
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
41
|
+
const body = {
|
|
42
|
+
payload: loginPayload,
|
|
43
|
+
signature,
|
|
44
|
+
};
|
|
45
|
+
const response = await axiosInstance.post('/auth/token', body, { headers });
|
|
46
|
+
const token = response.data.token;
|
|
47
|
+
|
|
48
|
+
return { token };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async verifyToken(token: string) {
|
|
52
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
53
|
+
const response = await axiosInstance.post('/auth/verify-token', { token }, { headers });
|
|
54
|
+
return response.data;
|
|
55
|
+
}
|
|
37
56
|
}
|
|
38
57
|
|
|
39
58
|
export const apiServices = new ApiServices();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { getToken } from '../constants/tokens.js';
|
|
3
|
+
|
|
4
|
+
export async function convertToTokenUnits(amount: number, chainId: number, contractAddress: string): Promise<ethers.BigNumberish> {
|
|
5
|
+
const token = await getToken(chainId, contractAddress);
|
|
6
|
+
const decimals = token.decimals;
|
|
7
|
+
const adjustedAmount = ethers.parseUnits(amount.toString(), decimals);
|
|
8
|
+
return adjustedAmount;
|
|
9
|
+
}
|
|
@@ -7,11 +7,11 @@ export function validateType(expectedType: string, value: any): boolean {
|
|
|
7
7
|
return typeof value === 'boolean';
|
|
8
8
|
case 'chainId':
|
|
9
9
|
case 'integer':
|
|
10
|
-
return Number.isInteger(value)
|
|
10
|
+
return Number.isInteger(value) || typeof value === 'bigint';
|
|
11
11
|
case 'int8': case 'int16': case 'int32': case 'int64': case 'int128': case 'int256':
|
|
12
|
-
return Number.isInteger(value) && isIntInRange(value, parseInt(expectedType.replace('int', '')));
|
|
12
|
+
return (Number.isInteger(value) || typeof value === 'bigint') && isIntInRange(value, parseInt(expectedType.replace('int', '')));
|
|
13
13
|
case 'uint8': case 'uint16': case 'uint32': case 'uint64': case 'uint128': case 'uint256':
|
|
14
|
-
return Number.isInteger(value) && isUintInRange(value, parseInt(expectedType.replace('uint', '')));
|
|
14
|
+
return (Number.isInteger(value) || typeof value === 'bigint') && isUintInRange(value, parseInt(expectedType.replace('uint', '')));
|
|
15
15
|
case 'erc20':
|
|
16
16
|
case 'nftCollection':
|
|
17
17
|
case 'address':
|
|
@@ -37,15 +37,32 @@ export function validateType(expectedType: string, value: any): boolean {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
export function typeIsNumber(type: string): boolean {
|
|
41
|
+
switch (type) {
|
|
42
|
+
case 'integer':
|
|
43
|
+
case 'float':
|
|
44
|
+
case 'fixed':
|
|
45
|
+
case 'ufixed':
|
|
46
|
+
case 'chainId':
|
|
47
|
+
case 'int8': case 'int16': case 'int32': case 'int64': case 'int128': case 'int256':
|
|
48
|
+
case 'uint8': case 'uint16': case 'uint32': case 'uint64': case 'uint128': case 'uint256':
|
|
49
|
+
return true;
|
|
50
|
+
default:
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
44
53
|
}
|
|
45
54
|
|
|
46
|
-
function
|
|
47
|
-
const
|
|
48
|
-
|
|
55
|
+
function isIntInRange(value: number | bigint, bits: number): boolean {
|
|
56
|
+
const min = BigInt(-(2 ** (bits - 1)));
|
|
57
|
+
const max = BigInt((2 ** (bits - 1)) - 1);
|
|
58
|
+
const bigIntValue = BigInt(value);
|
|
59
|
+
return bigIntValue >= min && bigIntValue <= max;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isUintInRange(value: number | bigint, bits: number): boolean {
|
|
63
|
+
const max = BigInt((2 ** bits) - 1);
|
|
64
|
+
const bigIntValue = BigInt(value);
|
|
65
|
+
return bigIntValue >= 0 && bigIntValue <= max;
|
|
49
66
|
}
|
|
50
67
|
|
|
51
68
|
export function isAddress(value: string): boolean {
|
|
@@ -63,4 +80,4 @@ export function isValidUrl(value: string): boolean {
|
|
|
63
80
|
|
|
64
81
|
export function isValidPhoneNumber(value: string): boolean {
|
|
65
82
|
return /^[\+]?[0-9]{0,3}\W?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im.test(value);
|
|
66
|
-
}
|
|
83
|
+
}
|