otomato-sdk 1.0.0

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.
Files changed (47) hide show
  1. package/.mocharc.json +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +67 -0
  4. package/dist/examples/create-trigger-list.js +136 -0
  5. package/dist/examples/create-trigger.js +7 -0
  6. package/dist/src/constants/ActionBlocks.js +321 -0
  7. package/dist/src/constants/chains.js +5 -0
  8. package/dist/src/constants/tokens.js +82 -0
  9. package/dist/src/index.js +13 -0
  10. package/dist/src/models/Action.js +1 -0
  11. package/dist/src/models/Automation.js +1 -0
  12. package/dist/src/models/Condition.js +1 -0
  13. package/dist/src/models/Parameter.js +1 -0
  14. package/dist/src/models/Trigger.js +110 -0
  15. package/dist/src/services/ApiService.js +1 -0
  16. package/dist/src/services/AutomationService.js +1 -0
  17. package/dist/test/trigger.spec.js +72 -0
  18. package/dist/types/examples/create-trigger-list.d.ts +1 -0
  19. package/dist/types/examples/create-trigger.d.ts +1 -0
  20. package/dist/types/src/constants/ActionBlocks.d.ts +91 -0
  21. package/dist/types/src/constants/chains.d.ts +5 -0
  22. package/dist/types/src/constants/tokens.d.ts +11 -0
  23. package/dist/types/src/index.d.ts +10 -0
  24. package/dist/types/src/models/Action.d.ts +6 -0
  25. package/dist/types/src/models/Automation.d.ts +6 -0
  26. package/dist/types/src/models/Condition.d.ts +6 -0
  27. package/dist/types/src/models/Parameter.d.ts +6 -0
  28. package/dist/types/src/models/Trigger.d.ts +37 -0
  29. package/dist/types/src/services/ApiService.d.ts +6 -0
  30. package/dist/types/src/services/AutomationService.d.ts +6 -0
  31. package/dist/types/test/trigger.spec.d.ts +1 -0
  32. package/examples/create-trigger-list.ts +159 -0
  33. package/examples/create-trigger.ts +12 -0
  34. package/package.json +37 -0
  35. package/src/constants/ActionBlocks.ts +324 -0
  36. package/src/constants/chains.ts +5 -0
  37. package/src/constants/tokens.ts +97 -0
  38. package/src/index.ts +15 -0
  39. package/src/models/Action.ts +6 -0
  40. package/src/models/Automation.ts +6 -0
  41. package/src/models/Condition.ts +6 -0
  42. package/src/models/Parameter.ts +6 -0
  43. package/src/models/Trigger.ts +128 -0
  44. package/src/services/ApiService.ts +6 -0
  45. package/src/services/AutomationService.ts +6 -0
  46. package/test/trigger.spec.ts +86 -0
  47. package/tsconfig.json +16 -0
@@ -0,0 +1,324 @@
1
+ import { Parameter } from '../models/Parameter.js';
2
+ import { CHAINS } from './chains.js';
3
+
4
+ const TRIGGER_TYPE = {
5
+ SUBSCRIPTION: 0,
6
+ POLLING: 1,
7
+ }
8
+
9
+ export const TRIGGERS = {
10
+ TOKENS: {
11
+ ERC20: {
12
+ CHAINS: [CHAINS.ALL],
13
+ TRANSFER: {
14
+ id: 1,
15
+ name: "Transfer token",
16
+ description: "Transfer an ERC-20 token",
17
+ type: TRIGGER_TYPE.SUBSCRIPTION,
18
+ parameters: [
19
+ {
20
+ key: "chainId",
21
+ type: "int",
22
+ description: "Chain ID of the ETH blockchain"
23
+ },
24
+ {
25
+ key: "abiParams.value",
26
+ type: "uint256",
27
+ description: "Amount of crypto to transfer"
28
+ },
29
+ {
30
+ key: "abiParams.to",
31
+ type: "address",
32
+ description: "Address to transfer crypto to"
33
+ },
34
+ {
35
+ key: "contractAddress",
36
+ type: "address",
37
+ description: "The contract address of the ERC20"
38
+ }
39
+ ] as Parameter[]
40
+ },
41
+ BALANCE: {
42
+ id: 1000,
43
+ name: "ERC20 balance check",
44
+ description: "Fetches the balance of an ERC20 and checks it against the specified condition.",
45
+ type: TRIGGER_TYPE.POLLING,
46
+ parameters: [
47
+ {
48
+ key: "chainId",
49
+ type: "int",
50
+ description: "Chain ID of the ETH blockchain"
51
+ },
52
+ {
53
+ key: "abiParams.account",
54
+ type: "address",
55
+ description: "Amount of crypto to transfer"
56
+ },
57
+ {
58
+ key: "contractAddress",
59
+ type: "address",
60
+ description: "The contract address of the ERC20"
61
+ },
62
+ {
63
+ key: "condition",
64
+ type: "logic_operator",
65
+ description: "Logic operator used for the comparison: <, >, <=, >=, ==, ..."
66
+ },
67
+ // todo: it should be in the same type as the output of the function
68
+ {
69
+ key: "comparisonValue",
70
+ type: "any",
71
+ description: "The value to compare to"
72
+ },
73
+ {
74
+ key: "interval",
75
+ type: "integer",
76
+ description: "The waiting time between each polling"
77
+ },
78
+ ] as Parameter[],
79
+ }
80
+ },
81
+ },
82
+ YIELD: {
83
+ SPLICE_FI: {
84
+ CHAINS: [CHAINS.MODE],
85
+ SWAP: {
86
+ id: 2,
87
+ name: "Splice Finance Swap",
88
+ description: "Swap in Splice Finance",
89
+ type: TRIGGER_TYPE.SUBSCRIPTION,
90
+ parameters: [
91
+ {
92
+ key: "abiParams.caller",
93
+ type: "address",
94
+ description: "Caller address"
95
+ },
96
+ {
97
+ key: "abiParams.market",
98
+ type: "address",
99
+ description: "Market address"
100
+ },
101
+ {
102
+ key: "abiParams.receiver",
103
+ type: "address",
104
+ description: "Receiver address"
105
+ },
106
+ {
107
+ key: "abiParams.netPtToAccount",
108
+ type: "int256",
109
+ description: "Net PT to account"
110
+ },
111
+ {
112
+ key: "abiParams.netSyToAccount",
113
+ type: "int256",
114
+ description: "Net SY to account"
115
+ }
116
+ ] as Parameter[]
117
+ },
118
+ LIQUIDITY_REMOVED: {
119
+ id: 6,
120
+ name: "Liquidity Removed",
121
+ description: "Liquidity removed in Splice Finance",
122
+ type: TRIGGER_TYPE.SUBSCRIPTION,
123
+ parameters: [
124
+ {
125
+ key: "abiParams.caller",
126
+ type: "address",
127
+ description: "Caller address"
128
+ },
129
+ {
130
+ key: "abiParams.market",
131
+ type: "address",
132
+ description: "Market address"
133
+ },
134
+ {
135
+ key: "abiParams.receiver",
136
+ type: "address",
137
+ description: "Receiver address"
138
+ },
139
+ {
140
+ key: "abiParams.netLpToRemove",
141
+ type: "uint256",
142
+ description: "Net LP to remove"
143
+ },
144
+ {
145
+ key: "abiParams.netPtOut",
146
+ type: "uint256",
147
+ description: "Net PT out"
148
+ },
149
+ {
150
+ key: "abiParams.netSyOut",
151
+ type: "uint256",
152
+ description: "Net SY out"
153
+ }
154
+ ] as Parameter[]
155
+ },
156
+ MARKET_CREATION: {
157
+ id: 7,
158
+ name: "Market Creation",
159
+ description: "Market creation in Splice Finance",
160
+ type: TRIGGER_TYPE.SUBSCRIPTION,
161
+ parameters: [
162
+ {
163
+ key: "abiParams.market",
164
+ type: "address",
165
+ description: "Market address"
166
+ },
167
+ {
168
+ key: "abiParams.PT",
169
+ type: "address",
170
+ description: "PT address"
171
+ },
172
+ {
173
+ key: "abiParams.scalarRoot",
174
+ type: "int256",
175
+ description: "Scalar root"
176
+ },
177
+ {
178
+ key: "abiParams.initialAnchor",
179
+ type: "int256",
180
+ description: "Initial anchor"
181
+ },
182
+ {
183
+ key: "abiParams.lnFeeRateRoot",
184
+ type: "uint256",
185
+ description: "LN fee rate root"
186
+ }
187
+ ] as Parameter[]
188
+ },
189
+ INTEREST_RATE_UPDATE: {
190
+ id: 9,
191
+ name: "Interest Rate Update",
192
+ description: "Interest rate update in Splice Finance",
193
+ type: TRIGGER_TYPE.SUBSCRIPTION,
194
+ parameters: [
195
+ {
196
+ key: "abiParams.timestamp",
197
+ type: "uint256",
198
+ description: "Timestamp"
199
+ },
200
+ {
201
+ key: "abiParams.lastLnImpliedRate",
202
+ type: "int256",
203
+ description: "Last LN implied rate"
204
+ },
205
+ {
206
+ key: "contractAddress",
207
+ type: "address",
208
+ description: "Contract address to monitor",
209
+ enum: [
210
+ "0xDE95511418EBD8Bd36294B11C86314DdFA50e212", // wrsETH
211
+ "0x34cf9BF641bd5f34197060A3f3478a1f97f78f0a", // ezETH
212
+ "0xb950A73Ea0842B0Cd06D0e369aE974799BB346f1", // MODE
213
+ "0xbF14932e1A7962C77D0b31be80075936bE1A43D4" // weETH
214
+ ]
215
+ }
216
+ ] as Parameter[]
217
+ }
218
+ }
219
+ },
220
+ LENDING: {
221
+ ASTARIA: {
222
+ CHAINS: [CHAINS.MODE],
223
+ LEND_RECALLED: {
224
+ id: 8,
225
+ name: "Lend Recalled",
226
+ description: "Lend recalled in Astaria",
227
+ type: TRIGGER_TYPE.SUBSCRIPTION,
228
+ parameters: [
229
+ {
230
+ key: "abiParams.loanId",
231
+ type: "uint256",
232
+ description: "Loan ID"
233
+ },
234
+ {
235
+ key: "abiParams.recaller",
236
+ type: "address",
237
+ description: "Recaller address"
238
+ },
239
+ {
240
+ key: "abiParams.end",
241
+ type: "uint256",
242
+ description: "End time"
243
+ }
244
+ ] as Parameter[]
245
+ }
246
+ }
247
+ },
248
+ DEXES: {
249
+ ODOS: {
250
+ CHAINS: [CHAINS.MODE, CHAINS.ETHEREUM],
251
+ SWAP: {
252
+ id: 4,
253
+ name: "Odos Swap",
254
+ description: "Swap on Odos",
255
+ type: TRIGGER_TYPE.SUBSCRIPTION,
256
+ parameters: [
257
+ {
258
+ key: "chainId",
259
+ type: "int",
260
+ description: "Chain ID of the ETH blockchain"
261
+ },
262
+ {
263
+ key: "abiParams.sender",
264
+ type: "address",
265
+ description: "Sender address"
266
+ },
267
+ {
268
+ key: "abiParams.inputAmount",
269
+ type: "uint256",
270
+ description: "Input amount"
271
+ },
272
+ {
273
+ key: "abiParams.inputToken",
274
+ type: "address",
275
+ description: "Input token address"
276
+ },
277
+ {
278
+ key: "abiParams.amountOut",
279
+ type: "uint256",
280
+ description: "Output amount"
281
+ },
282
+ {
283
+ key: "abiParams.outputToken",
284
+ type: "address",
285
+ description: "Output token address"
286
+ },
287
+ {
288
+ key: "abiParams.exchangeRate",
289
+ type: "float",
290
+ description: "Exchange rate"
291
+ }
292
+ ] as Parameter[]
293
+ }
294
+ }
295
+ },
296
+ SOCIALS: {
297
+ MODE_NAME_SERVICE: {
298
+ CHAINS: [CHAINS.MODE],
299
+ NAME_REGISTERED: {
300
+ id: 3,
301
+ name: "Name Registered",
302
+ description: "Name registered in Mode Name Service",
303
+ type: TRIGGER_TYPE.SUBSCRIPTION,
304
+ parameters: [
305
+ {
306
+ key: "abiParams.id",
307
+ type: "uint256",
308
+ description: "ID of the name registered"
309
+ },
310
+ {
311
+ key: "abiParams.owner",
312
+ type: "address",
313
+ description: "Owner address"
314
+ },
315
+ {
316
+ key: "abiParams.expires",
317
+ type: "uint256",
318
+ description: "Expiration time"
319
+ }
320
+ ] as Parameter[]
321
+ }
322
+ }
323
+ }
324
+ };
@@ -0,0 +1,5 @@
1
+ export const CHAINS = {
2
+ ALL: 0,
3
+ ETHEREUM: 1,
4
+ MODE: 43334,
5
+ };
@@ -0,0 +1,97 @@
1
+ export interface Token {
2
+ contractAddress: string;
3
+ name: string;
4
+ symbol: string;
5
+ decimals: number;
6
+ }
7
+
8
+ export interface Tokens {
9
+ [key: number]: Token[];
10
+ }
11
+
12
+ export const TOKENS: Tokens = {
13
+ 1: [
14
+ {
15
+ contractAddress: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
16
+ name: "USDC",
17
+ symbol: "USDC",
18
+ decimals: 6
19
+ },
20
+ ],
21
+ 43334: [
22
+ {
23
+ contractAddress: "0x0000000000000000000000000000000000000000",
24
+ name: "ETH",
25
+ symbol: "ETH",
26
+ decimals: 18
27
+ },
28
+ {
29
+ contractAddress: "0xd988097fb8612cc24eeC14542bC03424c656005f",
30
+ name: "USDC",
31
+ symbol: "USDC",
32
+ decimals: 6
33
+ },
34
+ {
35
+ contractAddress: '0xcDd475325D6F564d27247D1DddBb0DAc6fA0a5CF',
36
+ symbol: 'WBTC',
37
+ name: 'Wrapped BTC',
38
+ decimals: 8
39
+ },
40
+ {
41
+ contractAddress: '0xf0F161fDA2712DB8b566946122a5af183995e2eD',
42
+ symbol: 'USDT',
43
+ name: 'USDT',
44
+ decimals: 6
45
+ },
46
+ {
47
+ contractAddress: '0xDfc7C877a950e49D2610114102175A06C2e3167a',
48
+ symbol: 'MODE',
49
+ name: 'Mode',
50
+ decimals: 18
51
+ },
52
+ {
53
+ contractAddress: '0x71ef7EDa2Be775E5A7aa8afD02C45F059833e9d2',
54
+ symbol: 'ionWETH',
55
+ name: 'Ionic Wrapped Ether',
56
+ decimals: 18
57
+ },
58
+ {
59
+ contractAddress: '0x4200000000000000000000000000000000000006',
60
+ symbol: 'WETH',
61
+ name: 'Wrapped Ether',
62
+ decimals: 18
63
+ },
64
+ {
65
+ contractAddress: '0x59e710215d45F584f44c0FEe83DA6d43D762D857',
66
+ symbol: 'ionezETH',
67
+ name: 'Ionic Renzo Restaked ETH',
68
+ decimals: 18
69
+ },
70
+ {
71
+ contractAddress: '0x2416092f143378750bb29b79eD961ab195CcEea5',
72
+ symbol: 'ezETH',
73
+ name: 'Renzo Restaked ETH',
74
+ decimals: 18
75
+ },
76
+ {
77
+ contractAddress: '0x9c29a8eC901DBec4fFf165cD57D4f9E03D4838f7',
78
+ symbol: 'ironETH',
79
+ name: 'Ironclad ETH',
80
+ decimals: 18
81
+ },
82
+ ]
83
+ };
84
+
85
+ export function getToken(chain: number, symbol: string): Token {
86
+ if (!(chain in TOKENS)) {
87
+ throw new Error(`Unsupported chain: ${chain}`);
88
+ }
89
+
90
+ const token = TOKENS[chain].find(token => token.symbol === symbol);
91
+
92
+ if (!token) {
93
+ throw new Error(`Token ${symbol} not found on chain ${chain}`);
94
+ }
95
+
96
+ return token;
97
+ }
package/src/index.ts ADDED
@@ -0,0 +1,15 @@
1
+ // Exporting constants
2
+ export * from './constants/ActionBlocks.js';
3
+ export * from './constants/chains.js';
4
+ export * from './constants/tokens.js';
5
+
6
+ // Exporting models
7
+ export * from './models/Action.js';
8
+ export * from './models/Automation.js';
9
+ export * from './models/Condition.js';
10
+ export * from './models/Parameter.js';
11
+ export * from './models/Trigger.js';
12
+
13
+ // Exporting services
14
+ export * from './services/ApiService.js';
15
+ export * from './services/AutomationService.js';
@@ -0,0 +1,6 @@
1
+ export interface Action {
2
+ key: string;
3
+ type: string;
4
+ description: string;
5
+ value: any;
6
+ }
@@ -0,0 +1,6 @@
1
+ export interface Automation {
2
+ key: string;
3
+ type: string;
4
+ description: string;
5
+ value: any;
6
+ }
@@ -0,0 +1,6 @@
1
+ export interface COndition {
2
+ key: string;
3
+ type: string;
4
+ description: string;
5
+ value: any;
6
+ }
@@ -0,0 +1,6 @@
1
+ export interface Parameter {
2
+ key: string;
3
+ type: string;
4
+ description: string;
5
+ value: any;
6
+ }
@@ -0,0 +1,128 @@
1
+ import { Parameter } from './Parameter.js';
2
+ import { ethers } from 'ethers';
3
+
4
+ export class Trigger {
5
+ id: number;
6
+ name: string;
7
+ description: string;
8
+ type: number;
9
+ parameters: { [key: string]: Parameter };
10
+ keyMap: { [key: string]: string };
11
+
12
+ constructor(trigger: { id: number; name: string; description: string; type: number; parameters: Parameter[] }) {
13
+ this.id = trigger.id;
14
+ this.name = trigger.name;
15
+ this.description = trigger.description;
16
+ this.type = trigger.type;
17
+ this.parameters = {};
18
+ this.keyMap = {};
19
+ trigger.parameters.forEach(param => {
20
+ this.parameters[param.key] = { ...param, value: null };
21
+ const simplifiedKey = this.getSimplifiedKey(param.key);
22
+ this.keyMap[simplifiedKey] = param.key;
23
+ });
24
+ }
25
+
26
+ setChainId(value: number): void {
27
+ this.setParameter('chainId', value);
28
+ }
29
+
30
+ setContractAddress(value: string): void {
31
+ this.setParameter('contractAddress', value);
32
+ }
33
+
34
+ setCondition(value: string): void {
35
+ if (this.type !== 1) {
36
+ throw new Error('Condition setting is not applicable for subscription based triggers.');
37
+ }
38
+ this.setParameter('condition', value);
39
+ }
40
+
41
+ setComparisonValue(value: number): void {
42
+ if (this.type !== 1) {
43
+ throw new Error('Comparison value setting is not applicable for subscription based triggers.');
44
+ }
45
+ this.setParameter('comparisonValue', value);
46
+ }
47
+
48
+ setInterval(value: number): void {
49
+ if (this.type !== 1) {
50
+ throw new Error('Interval setting is not applicable for subscription based triggers.');
51
+ }
52
+ this.setParameter('interval', value);
53
+ }
54
+
55
+ setParams(key: string, value: any): void {
56
+ const fullKey = `abiParams.${key}`;
57
+ if (fullKey in this.parameters) {
58
+ this.setParameter(fullKey, value);
59
+ } else {
60
+ throw new Error(`Parameter with simplified key ${key} not found in abiParams`);
61
+ }
62
+ }
63
+
64
+ private setParameter(key: string, value: any): void {
65
+ if (key in this.parameters) {
66
+ const param = this.parameters[key];
67
+ if (this.validateType(param.type, value)) {
68
+ this.parameters[key].value = value;
69
+ } else {
70
+ throw new Error(`Invalid type for parameter ${key}. Expected ${param.type}.`);
71
+ }
72
+ } else {
73
+ throw new Error(`Parameter with key ${key} not found`);
74
+ }
75
+ }
76
+
77
+ private validateType(expectedType: string, value: any): boolean {
78
+ switch (expectedType) {
79
+ case 'int':
80
+ case 'integer':
81
+ case 'uint256':
82
+ case 'int256':
83
+ return Number.isInteger(value);
84
+ case 'address':
85
+ return typeof value === 'string' && this.isAddress(value);
86
+ case 'float':
87
+ return typeof value === 'number';
88
+ case 'logic_operator':
89
+ const validOperators = new Set(['<', '>', '<=', '>=', '==']);
90
+ return typeof value === 'string' && validOperators.has(value);
91
+ case 'any':
92
+ return true;
93
+ default:
94
+ return false;
95
+ }
96
+ }
97
+
98
+ private isAddress(value: string): boolean {
99
+ return ethers.isAddress(value);
100
+ }
101
+
102
+ getParameter(key: string): any {
103
+ if (key in this.parameters) {
104
+ return this.parameters[key].value;
105
+ } else {
106
+ throw new Error(`Parameter with key ${key} not found`);
107
+ }
108
+ }
109
+
110
+ getParameters(): { [key: string]: any } {
111
+ return Object.keys(this.parameters).reduce((acc, key) => {
112
+ acc[key] = this.parameters[key].value;
113
+ return acc;
114
+ }, {} as { [key: string]: any });
115
+ }
116
+
117
+ toJSON(): { [key: string]: any } {
118
+ const json: { [key: string]: any } = {
119
+ id: this.id,
120
+ parameters: this.getParameters(),
121
+ };
122
+ return json;
123
+ }
124
+
125
+ private getSimplifiedKey(key: string): string {
126
+ return key.replace(/[.\[\]]/g, '_');
127
+ }
128
+ }
@@ -0,0 +1,6 @@
1
+ export interface APISERVICES {
2
+ key: string;
3
+ type: string;
4
+ description: string;
5
+ value: any;
6
+ }
@@ -0,0 +1,6 @@
1
+ export interface AUTOSERVICES {
2
+ key: string;
3
+ type: string;
4
+ description: string;
5
+ value: any;
6
+ }