@defisaver/automation-sdk 2.0.8 → 2.1.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.
package/.env ADDED
@@ -0,0 +1,4 @@
1
+ RPC_1=https://mainnet.infura.io/v3/a3503e4501d040cd9ea2c913c68983a1
2
+ RPC_10=https://opt-mainnet.g.alchemy.com/v2/Pwh-hdbsP7Bf0CP_UMw4_Pw-NfHhSpIA
3
+ RPC_8453=https://base-mainnet.g.alchemy.com/v2/TERsAaPNcA7sgCVHHAMBvd95UtT4wCEf
4
+ RPC_42161=https://arb-mainnet.g.alchemy.com/v2/Pwh-hdbsP7Bf0CP_UMw4_Pw-NfHhSpIA
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ const decimal_js_1 = __importDefault(require("decimal.js"));
15
16
  const contractService_1 = require("../../services/contractService");
16
17
  const ethereumService_1 = require("../../services/ethereumService");
17
18
  const utils_1 = require("../../services/utils");
@@ -82,13 +83,18 @@ class LegacyAutomation extends Automation_1.default {
82
83
  }
83
84
  getParsedSubscriptions(addresses, options) {
84
85
  return __awaiter(this, void 0, void 0, function* () {
86
+ // Legacy automation was disabled on block 18213086
87
+ if (!(options === null || options === void 0 ? void 0 : options.fromBlock)
88
+ || (options === null || options === void 0 ? void 0 : options.fromBlock) === 'latest'
89
+ || (options === null || options === void 0 ? void 0 : options.fromBlock) === 'pending'
90
+ || ((options === null || options === void 0 ? void 0 : options.fromBlock) && new decimal_js_1.default(options === null || options === void 0 ? void 0 : options.fromBlock.toString()).lt(18213086))) {
91
+ return [];
92
+ }
85
93
  const subscriptions = yield this._getSubscriptions(addresses, options);
86
- // @ts-ignore
87
94
  return subscriptions.map((sub) => ({
88
95
  chainId: this.chainId,
89
96
  owner: sub[this.getOwnerPropName()],
90
- isEnabled: ((options === null || options === void 0 ? void 0 : options.fromBlock) && (options === null || options === void 0 ? void 0 : options.fromBlock) !== 'latest')
91
- ? (options === null || options === void 0 ? void 0 : options.fromBlock) > 18213086 : false,
97
+ isEnabled: true,
92
98
  protocol: this.protocol,
93
99
  specific: Object.assign({}, sub),
94
100
  strategy: {
@@ -20,6 +20,10 @@ export default class StrategiesAutomation extends Automation {
20
20
  protected getSubscriptionEventsFromSubStorage(options?: PastEventOptions): Promise<any[]>;
21
21
  protected getUpdateDataEventsFromSubStorage(options?: PastEventOptions): Promise<any[]>;
22
22
  protected getParsedSubscriptions(parseData: ParseData): Position.Automated | null;
23
+ /**
24
+ * @description Removes expired Limit Order subscriptions
25
+ */
26
+ protected removeExpiredSubscriptions(subscriptions: (Position.Automated | null)[]): (Position.Automated | null)[];
23
27
  protected _getSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
24
28
  getSubscriptions(options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
25
29
  getSubscriptionsFor(addresses: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const decimal_js_1 = __importDefault(require("decimal.js"));
16
+ const enums_1 = require("../../types/enums");
16
17
  const utils_1 = require("../../services/utils");
17
18
  const contractService_1 = require("../../services/contractService");
18
19
  const ethereumService_1 = require("../../services/ethereumService");
@@ -70,14 +71,38 @@ class StrategiesAutomation extends Automation_1.default {
70
71
  getParsedSubscriptions(parseData) {
71
72
  return (0, strategiesService_1.parseStrategiesAutomatedPosition)(parseData);
72
73
  }
74
+ /**
75
+ * @description Removes expired Limit Order subscriptions
76
+ */
77
+ removeExpiredSubscriptions(subscriptions) {
78
+ return subscriptions.filter((subscription) => {
79
+ if (!subscription) {
80
+ return true;
81
+ }
82
+ const { protocol, strategy, strategyData } = subscription;
83
+ if (protocol.id === enums_1.ProtocolIdentifiers.StrategiesAutomation.Exchange
84
+ && strategy.strategyId === enums_1.Strategies.Identifiers.LimitOrder) {
85
+ return new decimal_js_1.default(strategyData.decoded.triggerData.goodUntil).gt(new decimal_js_1.default(Date.now()).div(1000));
86
+ }
87
+ return true;
88
+ });
89
+ }
73
90
  _getSubscriptions(addresses, options) {
74
91
  return __awaiter(this, void 0, void 0, function* () {
75
92
  const _options = Object.assign(Object.assign({}, (0, utils_1.addToObjectIf)((0, utils_1.isDefined)(options), options)), (0, utils_1.addToObjectIf)((0, utils_1.isDefined)(addresses), { filter: { proxy: addresses } }));
76
- const subscriptionEvents = (yield this.getSubscriptionEventsFromSubStorage(_options)); // TODO PlaceholderType
93
+ let subscriptionEvents = (yield this.getSubscriptionEventsFromSubStorage(_options)); // TODO PlaceholderType
77
94
  let subscriptions = [];
78
95
  if (subscriptionEvents) {
79
- // @ts-ignore
80
- const strategiesSubs = yield this.getStrategiesSubs(subscriptionEvents.map((e) => e.returnValues.subId), _options.toBlock);
96
+ let strategiesSubs = yield this.getStrategiesSubs(subscriptionEvents.map((e) => e.returnValues.subId), _options.toBlock);
97
+ if (_options.enabledOnly) {
98
+ const filteredSubscriptionEvents = [];
99
+ strategiesSubs = strategiesSubs.filter((sub, index) => {
100
+ if (sub === null || sub === void 0 ? void 0 : sub.isEnabled)
101
+ filteredSubscriptionEvents.push(subscriptionEvents[index]);
102
+ return sub === null || sub === void 0 ? void 0 : sub.isEnabled;
103
+ });
104
+ subscriptionEvents = filteredSubscriptionEvents;
105
+ }
81
106
  subscriptions = yield Promise.all(strategiesSubs.map((sub, index) => __awaiter(this, void 0, void 0, function* () {
82
107
  var _a;
83
108
  let latestUpdate = subscriptionEvents[index].returnValues;
@@ -120,7 +145,7 @@ class StrategiesAutomation extends Automation_1.default {
120
145
  }, []);
121
146
  }
122
147
  }
123
- return subscriptions;
148
+ return _options.unexpiredOnly ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
124
149
  });
125
150
  }
126
151
  getSubscriptions(options) {
@@ -31,6 +31,14 @@ const enums_1 = require("../types/enums");
31
31
  const utils_1 = require("./utils");
32
32
  const subDataService = __importStar(require("./subDataService"));
33
33
  const triggerService = __importStar(require("./triggerService"));
34
+ const SPARK_MARKET_ADDRESSES = {
35
+ [enums_1.ChainId.Ethereum]: '0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE',
36
+ };
37
+ const AAVE_V3_MARKET_ADDRESSES = {
38
+ [enums_1.ChainId.Ethereum]: '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e',
39
+ [enums_1.ChainId.Optimism]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
40
+ [enums_1.ChainId.Arbitrum]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
41
+ };
34
42
  function parseMakerSavingsLiqProtection(position, parseData) {
35
43
  const _position = (0, lodash_1.cloneDeep)(position);
36
44
  const { subStruct } = parseData.subscriptionEventData;
@@ -38,6 +46,7 @@ function parseMakerSavingsLiqProtection(position, parseData) {
38
46
  const subData = subDataService.makerRepayFromSavingsSubData.decode(subStruct.subData);
39
47
  _position.strategyData.decoded.triggerData = triggerData;
40
48
  _position.strategyData.decoded.subData = subData;
49
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, subData.vaultId);
41
50
  _position.specific = {
42
51
  triggerRepayRatio: Number(triggerData.ratio),
43
52
  targetRepayRatio: Number(subData.targetRatio),
@@ -53,6 +62,7 @@ function parseMakerCloseOnPrice(position, parseData) {
53
62
  const subData = subDataService.makerCloseSubData.decode(subStruct.subData);
54
63
  _position.strategyData.decoded.triggerData = triggerData;
55
64
  _position.strategyData.decoded.subData = subData;
65
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, subData.vaultId);
56
66
  const isTakeProfit = (0, utils_1.isRatioStateOver)(Number(triggerData.state));
57
67
  _position.strategy.strategyId = isTakeProfit ? enums_1.Strategies.IdOverrides.TakeProfit : enums_1.Strategies.IdOverrides.StopLoss;
58
68
  _position.specific = {
@@ -68,6 +78,7 @@ function parseMakerTrailingStop(position, parseData) {
68
78
  const subData = subDataService.makerCloseSubData.decode(subStruct.subData);
69
79
  _position.strategyData.decoded.triggerData = triggerData;
70
80
  _position.strategyData.decoded.subData = subData;
81
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, subData.vaultId);
71
82
  _position.strategy.strategyId = enums_1.Strategies.IdOverrides.TrailingStop;
72
83
  _position.specific = {
73
84
  triggerPercentage: Number(triggerData.triggerPercentage),
@@ -84,6 +95,7 @@ function parseMakerLeverageManagement(position, parseData) {
84
95
  const subData = subDataService.makerLeverageManagementSubData.decode(subStruct.subData);
85
96
  _position.strategyData.decoded.triggerData = triggerData;
86
97
  _position.strategyData.decoded.subData = subData;
98
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, subData.vaultId);
87
99
  const isRepay = _position.strategy.strategyId === enums_1.Strategies.Identifiers.Repay;
88
100
  if (isRepay) {
89
101
  _position.specific = {
@@ -112,6 +124,7 @@ function parseLiquityCloseOnPrice(position, parseData) {
112
124
  const subData = subDataService.liquityCloseSubData.decode(subStruct.subData);
113
125
  _position.strategyData.decoded.triggerData = triggerData;
114
126
  _position.strategyData.decoded.subData = subData;
127
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
115
128
  const isTakeProfit = (0, utils_1.isRatioStateOver)(Number(triggerData.state));
116
129
  _position.strategy.strategyId = isTakeProfit ? enums_1.Strategies.IdOverrides.TakeProfit : enums_1.Strategies.IdOverrides.StopLoss;
117
130
  _position.specific = {
@@ -127,6 +140,7 @@ function parseLiquityTrailingStop(position, parseData) {
127
140
  const subData = subDataService.liquityCloseSubData.decode(subStruct.subData);
128
141
  _position.strategyData.decoded.triggerData = triggerData;
129
142
  _position.strategyData.decoded.subData = subData;
143
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
130
144
  _position.strategy.strategyId = enums_1.Strategies.IdOverrides.TrailingStop;
131
145
  _position.specific = {
132
146
  triggerPercentage: Number(triggerData.triggerPercentage),
@@ -143,6 +157,7 @@ function parseAaveV2LeverageManagement(position, parseData) {
143
157
  const subData = subDataService.aaveV2LeverageManagementSubData.decode(subStruct.subData);
144
158
  _position.strategyData.decoded.triggerData = triggerData;
145
159
  _position.strategyData.decoded.subData = subData;
160
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
146
161
  const isRepay = _position.strategy.strategyId === enums_1.Strategies.Identifiers.Repay;
147
162
  if (isRepay) {
148
163
  _position.specific = {
@@ -172,6 +187,7 @@ function parseAaveV3LeverageManagement(position, parseData) {
172
187
  const subData = subDataService.aaveV3LeverageManagementSubData.decode(subStruct.subData);
173
188
  _position.strategyData.decoded.triggerData = triggerData;
174
189
  _position.strategyData.decoded.subData = subData;
190
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
175
191
  const isRepay = _position.strategy.strategyId === enums_1.Strategies.Identifiers.Repay;
176
192
  if (isRepay) {
177
193
  _position.specific = {
@@ -201,6 +217,7 @@ function parseMorphoAaveV2LeverageManagement(position, parseData) {
201
217
  const subData = subDataService.morphoAaveV2LeverageManagementSubData.decode(subStruct.subData);
202
218
  _position.strategyData.decoded.triggerData = triggerData;
203
219
  _position.strategyData.decoded.subData = subData;
220
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
204
221
  const isRepay = _position.strategy.strategyId === enums_1.Strategies.Identifiers.Repay;
205
222
  if (isRepay) {
206
223
  _position.specific = {
@@ -229,6 +246,7 @@ function parseAaveV3CloseOnPrice(position, parseData) {
229
246
  const subData = subDataService.aaveV3QuotePriceSubData.decode(subStruct.subData);
230
247
  _position.strategyData.decoded.triggerData = triggerData;
231
248
  _position.strategyData.decoded.subData = subData;
249
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
232
250
  _position.specific = {
233
251
  collAsset: subData.collAsset,
234
252
  collAssetId: subData.collAssetId,
@@ -250,6 +268,7 @@ function parseAaveV3CloseOnPriceWithMaximumGasPrice(position, parseData) {
250
268
  const subData = subDataService.aaveV3QuotePriceSubData.decode(subStruct.subData);
251
269
  _position.strategyData.decoded.triggerData = triggerData;
252
270
  _position.strategyData.decoded.subData = subData;
271
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
253
272
  _position.specific = {
254
273
  collAsset: subData.collAsset,
255
274
  collAssetId: subData.collAssetId,
@@ -275,7 +294,8 @@ function parseCompoundV2LeverageManagement(position, parseData) {
275
294
  const subData = subDataService.compoundV2LeverageManagementSubData.decode(subStruct.subData);
276
295
  _position.strategyData.decoded.triggerData = triggerData;
277
296
  _position.strategyData.decoded.subData = subData;
278
- _position.owner = triggerData.owner;
297
+ _position.owner = triggerData.owner.toLowerCase();
298
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
279
299
  const isRepay = [enums_1.Strategies.Identifiers.Repay, enums_1.Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId);
280
300
  if (isRepay) {
281
301
  _position.specific = {
@@ -305,7 +325,8 @@ function parseCompoundV3LeverageManagement(position, parseData) {
305
325
  const subData = subDataService.compoundV3LeverageManagementSubData.decode(subStruct.subData);
306
326
  _position.strategyData.decoded.triggerData = triggerData;
307
327
  _position.strategyData.decoded.subData = subData;
308
- _position.owner = triggerData.owner;
328
+ _position.owner = triggerData.owner.toLowerCase();
329
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
309
330
  const isRepay = [enums_1.Strategies.Identifiers.Repay, enums_1.Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId);
310
331
  if (isRepay) {
311
332
  _position.specific = {
@@ -333,14 +354,16 @@ function parseChickenBondsRebond(position, parseData) {
333
354
  const { subStruct } = parseData.subscriptionEventData;
334
355
  _position.strategyData.decoded.triggerData = triggerService.cBondsRebondTrigger.decode(subStruct.triggerData);
335
356
  _position.strategyData.decoded.subData = subDataService.cBondsRebondSubData.decode(subStruct.subData);
357
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.strategyData.decoded.triggerData.bondId);
336
358
  return _position;
337
359
  }
338
360
  function parseLiquityBondProtection(position, parseData) {
339
361
  const _position = (0, lodash_1.cloneDeep)(position);
340
362
  const { subStruct } = parseData.subscriptionEventData;
341
363
  const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
342
- _position.strategyData.decoded.subData = subDataService.liquityPaybackUsingChickenBondSubData.decode(subStruct.subData);
343
364
  _position.strategyData.decoded.triggerData = triggerData;
365
+ _position.strategyData.decoded.subData = subDataService.liquityPaybackUsingChickenBondSubData.decode(subStruct.subData);
366
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
344
367
  _position.specific = {
345
368
  triggerRepayRatio: Number(triggerData.ratio),
346
369
  targetRepayRatio: Infinity,
@@ -353,6 +376,7 @@ function parseExchangeDca(position, parseData, chainId) {
353
376
  const { subStruct } = parseData.subscriptionEventData;
354
377
  _position.strategyData.decoded.triggerData = triggerService.exchangeTimestampTrigger.decode(subStruct.triggerData);
355
378
  _position.strategyData.decoded.subData = subDataService.exchangeDcaSubData.decode(subStruct.subData, chainId);
379
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, Math.random());
356
380
  return _position;
357
381
  }
358
382
  function parseExchangeLimitOrder(position, parseData, chainId) {
@@ -362,6 +386,7 @@ function parseExchangeLimitOrder(position, parseData, chainId) {
362
386
  const fromTokenDecimals = (0, tokens_1.getAssetInfoByAddress)(_position.strategyData.decoded.subData.fromToken, chainId).decimals;
363
387
  const toTokenDecimals = (0, tokens_1.getAssetInfoByAddress)(_position.strategyData.decoded.subData.toToken, chainId).decimals;
364
388
  _position.strategyData.decoded.triggerData = triggerService.exchangeOffchainPriceTrigger.decode(subStruct.triggerData, fromTokenDecimals, toTokenDecimals);
389
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, Math.random());
365
390
  return _position;
366
391
  }
367
392
  function parseLiquityLeverageManagement(position, parseData) {
@@ -372,6 +397,7 @@ function parseLiquityLeverageManagement(position, parseData) {
372
397
  const subData = subDataService.liquityLeverageManagementSubData.decode(subStruct.subData);
373
398
  _position.strategyData.decoded.triggerData = triggerData;
374
399
  _position.strategyData.decoded.subData = subData;
400
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
375
401
  const isRepay = _position.strategy.strategyId === enums_1.Strategies.Identifiers.Repay;
376
402
  if (isRepay) {
377
403
  _position.specific = {
@@ -401,6 +427,7 @@ function parseSparkLeverageManagement(position, parseData) {
401
427
  const subData = subDataService.sparkLeverageManagementSubData.decode(subStruct.subData);
402
428
  _position.strategyData.decoded.triggerData = triggerData;
403
429
  _position.strategyData.decoded.subData = subData;
430
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
404
431
  const isRepay = _position.strategy.strategyId === enums_1.Strategies.Identifiers.Repay;
405
432
  if (isRepay) {
406
433
  _position.specific = {
@@ -429,6 +456,7 @@ function parseSparkCloseOnPrice(position, parseData) {
429
456
  const subData = subDataService.sparkQuotePriceSubData.decode(subStruct.subData);
430
457
  _position.strategyData.decoded.triggerData = triggerData;
431
458
  _position.strategyData.decoded.subData = subData;
459
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, SPARK_MARKET_ADDRESSES[_position.chainId]);
432
460
  _position.specific = {
433
461
  collAsset: subData.collAsset,
434
462
  collAssetId: subData.collAssetId,
@@ -450,6 +478,7 @@ function parseLiquitySavingsLiqProtection(position, parseData) {
450
478
  const subData = subDataService.liquityRepayFromSavingsSubData.decode(subStruct.subData);
451
479
  _position.strategyData.decoded.triggerData = triggerData;
452
480
  _position.strategyData.decoded.subData = subData;
481
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
453
482
  _position.specific = {
454
483
  triggerRepayRatio: triggerData.ratio,
455
484
  targetRepayRatio: subData.targetRatio,
@@ -458,13 +487,14 @@ function parseLiquitySavingsLiqProtection(position, parseData) {
458
487
  };
459
488
  return _position;
460
489
  }
461
- function parseDebtInFrontRepay(position, parseData) {
490
+ function parseLiquityDebtInFrontRepay(position, parseData) {
462
491
  const _position = (0, lodash_1.cloneDeep)(position);
463
492
  const { subStruct } = parseData.subscriptionEventData;
464
493
  const triggerData = triggerService.liquityDebtInFrontWithLimitTrigger.decode(subStruct.triggerData);
465
494
  const subData = subDataService.liquityDebtInFrontRepaySubData.decode(subStruct.subData);
466
495
  _position.strategyData.decoded.triggerData = triggerData;
467
496
  _position.strategyData.decoded.subData = subData;
497
+ _position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner);
468
498
  _position.specific = {
469
499
  debtInFrontMin: triggerData.debtInFrontMin,
470
500
  targetRepayRatioIncrease: subData.targetRatioIncrease,
@@ -489,7 +519,7 @@ const parsingMethodsMapping = {
489
519
  [enums_1.Strategies.Identifiers.Boost]: parseLiquityLeverageManagement,
490
520
  [enums_1.Strategies.Identifiers.SavingsDsrPayback]: parseLiquitySavingsLiqProtection,
491
521
  [enums_1.Strategies.Identifiers.SavingsDsrSupply]: parseLiquitySavingsLiqProtection,
492
- [enums_1.Strategies.Identifiers.DebtInFrontRepay]: parseDebtInFrontRepay,
522
+ [enums_1.Strategies.Identifiers.DebtInFrontRepay]: parseLiquityDebtInFrontRepay,
493
523
  },
494
524
  [enums_1.ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
495
525
  [enums_1.Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
@@ -549,8 +579,9 @@ function parseStrategiesAutomatedPosition(parseData) {
549
579
  chainId,
550
580
  subHash,
551
581
  blockNumber,
582
+ positionId: 'positionId parsing not implemented.',
552
583
  subId: Number(subId),
553
- owner: proxy,
584
+ owner: proxy.toLowerCase(),
554
585
  protocol: Object.assign({}, strategyOrBundleInfo.protocol),
555
586
  strategy: Object.assign({ isBundle: subStruct.isBundle }, strategyOrBundleInfo),
556
587
  strategyData: {
@@ -20,10 +20,11 @@ describe('Feature: strategiesService.ts', () => {
20
20
  {
21
21
  isEnabled: true,
22
22
  chainId: 1,
23
+ positionId: '1-aave__v3-0x9cb7e19861665366011899d74e75d4f2a419aeed-0x2f39d218133afab8f2b819b1066c7e434ad94e9e',
23
24
  subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
24
25
  blockNumber: 18015756,
25
26
  subId: 379,
26
- owner: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
27
+ owner: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
27
28
  protocol: {
28
29
  id: enums_1.ProtocolIdentifiers.StrategiesAutomation.AaveV3,
29
30
  name: 'Aave',
@@ -78,7 +79,7 @@ describe('Feature: strategiesService.ts', () => {
78
79
  blockNumber: 18015756,
79
80
  subscriptionEventData: {
80
81
  subId: '379',
81
- proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
82
+ proxy: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
82
83
  subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
83
84
  // @ts-ignore
84
85
  subStruct: {
@@ -22,3 +22,4 @@ export declare function getRatioStateInfoForAaveCloseStrategy(currentRatioState:
22
22
  shouldFlip: boolean;
23
23
  ratioState: RatioState;
24
24
  };
25
+ export declare function getPositionId(...args: (number | string)[]): string;
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.getRatioStateInfoForAaveCloseStrategy = exports.requireAddresses = exports.requireAddress = exports.isEmptyBytes = exports.isRatioStateUnder = exports.isRatioStateOver = exports.weiToRatioPercentage = exports.ratioPercentageToWei = exports.encodeSubId = exports.compareSubHashes = exports.wethToEthByAddress = exports.wethToEth = exports.ethToWeth = exports.addToObjectIf = exports.addToArrayIf = exports.isAddress = exports.compareAddresses = exports.isUndefined = exports.isDefined = void 0;
29
+ exports.getPositionId = exports.getRatioStateInfoForAaveCloseStrategy = exports.requireAddresses = exports.requireAddress = exports.isEmptyBytes = exports.isRatioStateUnder = exports.isRatioStateOver = exports.weiToRatioPercentage = exports.ratioPercentageToWei = exports.encodeSubId = exports.compareSubHashes = exports.wethToEthByAddress = exports.wethToEth = exports.ethToWeth = exports.addToObjectIf = exports.addToArrayIf = exports.isAddress = exports.compareAddresses = exports.isUndefined = exports.isDefined = void 0;
30
30
  const decimal_js_1 = __importDefault(require("decimal.js"));
31
31
  const web3Utils = __importStar(require("web3-utils"));
32
32
  const web3_eth_abi_1 = __importDefault(require("web3-eth-abi"));
@@ -125,3 +125,7 @@ function getRatioStateInfoForAaveCloseStrategy(currentRatioState, collAsset, deb
125
125
  return { shouldFlip, ratioState };
126
126
  }
127
127
  exports.getRatioStateInfoForAaveCloseStrategy = getRatioStateInfoForAaveCloseStrategy;
128
+ function getPositionId(...args) {
129
+ return args.map(arg => arg.toString().toLowerCase().split(' ').join('_')).join('-');
130
+ }
131
+ exports.getPositionId = getPositionId;
@@ -359,4 +359,17 @@ describe('Feature: utils.ts', () => {
359
359
  });
360
360
  });
361
361
  });
362
+ describe('When testing utils.getPositionId()', () => {
363
+ const examples = [
364
+ [
365
+ '1-aave__v3-0x9cb7e19861665366011899d74e75d4f2a419aeed-0x2f39d218133afab8f2b819b1066c7e434ad94e9e',
366
+ [1, enums_1.ProtocolIdentifiers.StrategiesAutomation.AaveV3, '0x9cB7E19861665366011899d74E75d4F2A419aEeD', '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e']
367
+ ],
368
+ ];
369
+ examples.forEach(([expected, actual]) => {
370
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
371
+ (0, chai_1.expect)((0, utils_1.getPositionId)(...actual)).to.eql(expected);
372
+ });
373
+ });
374
+ });
362
375
  });
@@ -45,11 +45,14 @@ export declare namespace Multicall {
45
45
  }
46
46
  type Payload = any[];
47
47
  }
48
- export interface SubscriptionOptions {
48
+ interface _SubscriptionOptions {
49
49
  toBlock: BlockNumber;
50
50
  fromBlock: BlockNumber;
51
- mergeWithSameId?: boolean;
51
+ mergeWithSameId: boolean;
52
+ enabledOnly: boolean;
53
+ unexpiredOnly: boolean;
52
54
  }
55
+ export type SubscriptionOptions = Partial<_SubscriptionOptions>;
53
56
  export declare namespace Interfaces {
54
57
  interface ProtocolBase {
55
58
  id: ProtocolIdentifiers.StrategiesAutomation | ProtocolIdentifiers.LegacyAutomation;
@@ -140,6 +143,7 @@ export declare namespace Position {
140
143
  type SpecificAny = Specific.CloseOnPrice | Specific.TrailingStop | Specific.RatioProtection | Specific.CloseOnPriceAave | Specific.CloseOnPriceWithMaximumGasPriceAave | Specific.DebtInFrontRepay;
141
144
  interface Automated {
142
145
  chainId: ChainId;
146
+ positionId: string;
143
147
  owner: EthereumAddress;
144
148
  subId: number;
145
149
  subIds?: number[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/automation-sdk",
3
- "version": "2.0.8",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "main": "./umd/index.js",
6
6
  "module": "./esm/index.js",
@@ -21,9 +21,9 @@
21
21
  "repository": "https://github.com/defisaver/automation-sdk",
22
22
  "license": "ISC",
23
23
  "dependencies": {
24
- "@defisaver/eslint-config": "^1.0.0",
25
- "@defisaver/sdk": "^1.0.43",
26
- "@defisaver/tokens": "^1.4.55",
24
+ "@defisaver/eslint-config": "^1.0.1",
25
+ "@defisaver/sdk": "^1.0.55",
26
+ "@defisaver/tokens": "^1.5.3",
27
27
  "@ethersproject/address": "^5.0.10",
28
28
  "@ethersproject/solidity": "^5.0.9",
29
29
  "decimal.js": "^10.4.3",
@@ -1,3 +1,5 @@
1
+ import Dec from 'decimal.js';
2
+
1
3
  import type Web3 from 'web3';
2
4
  import type {
3
5
  EthereumAddress, Position, Interfaces, Contract, PlaceholderType, SubscriptionOptions,
@@ -99,14 +101,22 @@ export default class LegacyAutomation extends Automation {
99
101
  }
100
102
 
101
103
  protected async getParsedSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<Position.LegacyAutomated[]> {
104
+ // Legacy automation was disabled on block 18213086
105
+ if (
106
+ !options?.fromBlock
107
+ || options?.fromBlock === 'latest'
108
+ || options?.fromBlock === 'pending'
109
+ || (options?.fromBlock && new Dec(options?.fromBlock.toString()).lt(18213086))
110
+ ) {
111
+ return [];
112
+ }
113
+
102
114
  const subscriptions = await this._getSubscriptions(addresses, options);
103
115
 
104
- // @ts-ignore
105
- return subscriptions.map((sub) => ({
116
+ return subscriptions.map((sub: any) => ({
106
117
  chainId: this.chainId,
107
118
  owner: sub[this.getOwnerPropName()],
108
- isEnabled: (options?.fromBlock && options?.fromBlock !== 'latest')
109
- ? options?.fromBlock > 18213086 : false, // Legacy automation was disabled on block 18213086
119
+ isEnabled: true,
110
120
  protocol: this.protocol,
111
121
  specific: { ...sub },
112
122
  strategy: {
@@ -8,6 +8,7 @@ import type {
8
8
  StrategyModel, SubStorage,
9
9
  } from '../../types/contracts/generated/SubStorage';
10
10
  import type { ChainId } from '../../types/enums';
11
+ import { Strategies, ProtocolIdentifiers } from '../../types/enums';
11
12
 
12
13
  import { addToObjectIf, isDefined } from '../../services/utils';
13
14
  import { getAbiItem, makeSubStorageContract } from '../../services/contractService';
@@ -84,20 +85,53 @@ export default class StrategiesAutomation extends Automation {
84
85
  return parseStrategiesAutomatedPosition(parseData);
85
86
  }
86
87
 
88
+ /**
89
+ * @description Removes expired Limit Order subscriptions
90
+ */
91
+ protected removeExpiredSubscriptions(subscriptions: (Position.Automated | null)[]) {
92
+ return subscriptions.filter((subscription: Position.Automated | null) => {
93
+ if (!subscription) {
94
+ return true;
95
+ }
96
+
97
+ const { protocol, strategy, strategyData } = subscription;
98
+
99
+ if (
100
+ protocol.id === ProtocolIdentifiers.StrategiesAutomation.Exchange
101
+ && strategy.strategyId === Strategies.Identifiers.LimitOrder
102
+ ) {
103
+ return new Dec(strategyData.decoded.triggerData.goodUntil).gt(new Dec(Date.now()).div(1000));
104
+ }
105
+
106
+ return true;
107
+ });
108
+ }
109
+
87
110
  protected async _getSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]> {
88
111
  const _options = {
89
112
  ...addToObjectIf(isDefined(options), options),
90
113
  ...addToObjectIf(isDefined(addresses), { filter: { proxy: addresses } }),
91
- };
114
+ } as SubscriptionOptions & PastEventOptions;
92
115
 
93
-
94
- const subscriptionEvents = (await this.getSubscriptionEventsFromSubStorage(_options)) as PlaceholderType; // TODO PlaceholderType
116
+ let subscriptionEvents = (await this.getSubscriptionEventsFromSubStorage(_options)) as PlaceholderType; // TODO PlaceholderType
95
117
 
96
118
  let subscriptions: (Position.Automated | null)[] = [];
97
119
 
98
120
  if (subscriptionEvents) {
99
- // @ts-ignore
100
- const strategiesSubs = await this.getStrategiesSubs(subscriptionEvents.map((e) => e.returnValues.subId), _options.toBlock);
121
+ let strategiesSubs = await this.getStrategiesSubs(
122
+ subscriptionEvents.map((e: { returnValues: { subId: number } }) => e.returnValues.subId), _options.toBlock,
123
+ );
124
+
125
+ if (_options.enabledOnly) {
126
+ const filteredSubscriptionEvents = [] as PlaceholderType;
127
+
128
+ strategiesSubs = strategiesSubs.filter((sub, index) => {
129
+ if (sub?.isEnabled) filteredSubscriptionEvents.push(subscriptionEvents[index]);
130
+ return sub?.isEnabled;
131
+ });
132
+
133
+ subscriptionEvents = filteredSubscriptionEvents;
134
+ }
101
135
 
102
136
  subscriptions = await Promise.all(strategiesSubs.map(async (sub, index: number) => {
103
137
  let latestUpdate = subscriptionEvents[index].returnValues;
@@ -168,7 +202,7 @@ export default class StrategiesAutomation extends Automation {
168
202
  }
169
203
  }
170
204
 
171
- return subscriptions;
205
+ return _options.unexpiredOnly ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
172
206
  }
173
207
 
174
208
  public async getSubscriptions(options?: SubscriptionOptions): Promise<(Position.Automated | null)[]> {
@@ -13,10 +13,11 @@ describe('Feature: strategiesService.ts', () => {
13
13
  {
14
14
  isEnabled: true,
15
15
  chainId: 1,
16
+ positionId: '1-aave__v3-0x9cb7e19861665366011899d74e75d4f2a419aeed-0x2f39d218133afab8f2b819b1066c7e434ad94e9e',
16
17
  subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
17
18
  blockNumber: 18015756,
18
19
  subId: 379,
19
- owner: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
20
+ owner: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
20
21
  protocol: {
21
22
  id: ProtocolIdentifiers.StrategiesAutomation.AaveV3,
22
23
  name: 'Aave',
@@ -71,7 +72,7 @@ describe('Feature: strategiesService.ts', () => {
71
72
  blockNumber: 18015756,
72
73
  subscriptionEventData: {
73
74
  subId: '379',
74
- proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
75
+ proxy: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
75
76
  subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
76
77
  // @ts-ignore
77
78
  subStruct: