@defisaver/automation-sdk 3.3.21-debt-switch-dev-dev → 3.3.21

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 (52) hide show
  1. package/cjs/automation/private/StrategiesAutomation.d.ts +5 -1
  2. package/cjs/automation/private/StrategiesAutomation.js +12 -0
  3. package/cjs/automation/private/StrategiesAutomation.test.js +51 -0
  4. package/cjs/constants/index.js +0 -40
  5. package/cjs/services/apiSubscriptionsService.d.ts +7 -0
  6. package/cjs/services/apiSubscriptionsService.js +33 -0
  7. package/cjs/services/apiSubscriptionsService.test.d.ts +1 -0
  8. package/cjs/services/apiSubscriptionsService.test.js +67 -0
  9. package/cjs/services/strategiesService.js +0 -13
  10. package/cjs/services/strategiesService.test.js +0 -1
  11. package/cjs/services/strategySubService.d.ts +0 -1
  12. package/cjs/services/strategySubService.js +0 -6
  13. package/cjs/services/strategySubService.test.js +0 -71
  14. package/cjs/services/subDataService.d.ts +0 -12
  15. package/cjs/services/subDataService.js +2 -34
  16. package/cjs/services/subDataService.test.js +0 -104
  17. package/cjs/types/enums.d.ts +4 -14
  18. package/cjs/types/enums.js +0 -10
  19. package/cjs/types/index.d.ts +24 -2
  20. package/esm/automation/private/StrategiesAutomation.d.ts +5 -1
  21. package/esm/automation/private/StrategiesAutomation.js +12 -0
  22. package/esm/automation/private/StrategiesAutomation.test.js +51 -0
  23. package/esm/constants/index.js +0 -40
  24. package/esm/services/apiSubscriptionsService.d.ts +7 -0
  25. package/esm/services/apiSubscriptionsService.js +29 -0
  26. package/esm/services/apiSubscriptionsService.test.d.ts +1 -0
  27. package/esm/services/apiSubscriptionsService.test.js +65 -0
  28. package/esm/services/strategiesService.js +0 -13
  29. package/esm/services/strategiesService.test.js +0 -1
  30. package/esm/services/strategySubService.d.ts +0 -1
  31. package/esm/services/strategySubService.js +0 -6
  32. package/esm/services/strategySubService.test.js +0 -71
  33. package/esm/services/subDataService.d.ts +0 -12
  34. package/esm/services/subDataService.js +0 -32
  35. package/esm/services/subDataService.test.js +0 -104
  36. package/esm/types/enums.d.ts +4 -14
  37. package/esm/types/enums.js +0 -10
  38. package/esm/types/index.d.ts +24 -2
  39. package/package.json +1 -1
  40. package/src/automation/private/StrategiesAutomation.test.ts +65 -1
  41. package/src/automation/private/StrategiesAutomation.ts +17 -0
  42. package/src/constants/index.ts +0 -40
  43. package/src/services/apiSubscriptionsService.test.ts +73 -0
  44. package/src/services/apiSubscriptionsService.ts +33 -0
  45. package/src/services/strategiesService.test.ts +0 -1
  46. package/src/services/strategiesService.ts +0 -15
  47. package/src/services/strategySubService.test.ts +0 -89
  48. package/src/services/strategySubService.ts +0 -22
  49. package/src/services/subDataService.test.ts +0 -108
  50. package/src/services/subDataService.ts +0 -50
  51. package/src/types/enums.ts +0 -10
  52. package/src/types/index.ts +26 -2
@@ -510,110 +510,6 @@ describe('Feature: subDataService.ts', () => {
510
510
  });
511
511
  });
512
512
  });
513
- describe('When testing subDataService.aaveV3DebtSwitchSubData', () => {
514
- describe('encode()', () => {
515
- const examples = [
516
- // USDC -> DAI
517
- [
518
- [
519
- '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
520
- '0x0000000000000000000000000000000000000000000000000000000000000001',
521
- '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
522
- '0x0000000000000000000000000000000000000000000000000000000000000003',
523
- '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
524
- '0x0000000000000000000000000000000000000000000000008ac7230489e80000',
525
- '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
526
- ],
527
- [
528
- web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
529
- 1,
530
- web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
531
- 3,
532
- web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
533
- '10000000000000000000',
534
- web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
535
- ]
536
- ],
537
- // DAI -> USDC (MaxUint256)
538
- [
539
- [
540
- '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
541
- '0x0000000000000000000000000000000000000000000000000000000000000003',
542
- '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
543
- '0x0000000000000000000000000000000000000000000000000000000000000001',
544
- '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
545
- '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
546
- '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
547
- ],
548
- [
549
- web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
550
- 3,
551
- web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
552
- 1,
553
- web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
554
- MAXUINT,
555
- web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
556
- ]
557
- ],
558
- ];
559
- examples.forEach(([expected, actual]) => {
560
- it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
561
- expect(subDataService.aaveV3DebtSwitchSubData.encode(...actual)).to.eql(expected);
562
- });
563
- });
564
- });
565
- describe('decode()', () => {
566
- const examples = [
567
- // USDC -> DAI
568
- [
569
- {
570
- fromAsset: web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
571
- fromAssetId: 1,
572
- toAsset: web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
573
- toAssetId: 3,
574
- marketAddr: web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
575
- amountToSwitch: '10000000000000000000',
576
- user: web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
577
- },
578
- [
579
- '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
580
- '0x0000000000000000000000000000000000000000000000000000000000000001',
581
- '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
582
- '0x0000000000000000000000000000000000000000000000000000000000000003',
583
- '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
584
- '0x0000000000000000000000000000000000000000000000008ac7230489e80000',
585
- '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
586
- ],
587
- ],
588
- // DAI -> USDC (MaxUint256)
589
- [
590
- {
591
- fromAsset: web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
592
- fromAssetId: 3,
593
- toAsset: web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
594
- toAssetId: 1,
595
- marketAddr: web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
596
- amountToSwitch: MAXUINT,
597
- user: web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
598
- },
599
- [
600
- '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
601
- '0x0000000000000000000000000000000000000000000000000000000000000003',
602
- '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
603
- '0x0000000000000000000000000000000000000000000000000000000000000001',
604
- '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
605
- '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
606
- '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
607
- ],
608
- ],
609
- ];
610
- examples.forEach(([expected, actual]) => {
611
- it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
612
- expect(subDataService.aaveV3DebtSwitchSubData.decode(actual)).to.eql(expected);
613
- });
614
- });
615
- });
616
- });
617
513
  describe('When testing subDataService.sparkCollateralSwitchSubData', () => {
618
514
  describe('encode()', () => {
619
515
  const examples = [
@@ -91,30 +91,22 @@ export declare namespace Strategies {
91
91
  AAVE_V4_COLLATERAL_SWITCH = 154,
92
92
  AAVE_V4_COLLATERAL_SWITCH_EOA = 155,
93
93
  SPARK_COLLATERAL_SWITCH = 156,
94
- SPARK_GENERIC_FL_COLLATERAL_SWITCH = 167,
95
- AAVE_V3_DEBT_SWITCH = 168,
96
- AAVE_V3_DEBT_SWITCH_EOA = 169
94
+ SPARK_GENERIC_FL_COLLATERAL_SWITCH = 167
97
95
  }
98
96
  enum OptimismIds {
99
97
  EXCHANGE_DCA = 8,
100
98
  EXCHANGE_LIMIT_ORDER = 9,
101
- AAVE_V3_COLLATERAL_SWITCH = 24,
102
- AAVE_V3_DEBT_SWITCH = 25,
103
- AAVE_V3_DEBT_SWITCH_EOA = 26
99
+ AAVE_V3_COLLATERAL_SWITCH = 24
104
100
  }
105
101
  enum BaseIds {
106
102
  EXCHANGE_DCA = 8,
107
103
  EXCHANGE_LIMIT_ORDER = 9,
108
- AAVE_V3_COLLATERAL_SWITCH = 56,
109
- AAVE_V3_DEBT_SWITCH = 61,
110
- AAVE_V3_DEBT_SWITCH_EOA = 62
104
+ AAVE_V3_COLLATERAL_SWITCH = 56
111
105
  }
112
106
  enum ArbitrumIds {
113
107
  EXCHANGE_DCA = 8,
114
108
  EXCHANGE_LIMIT_ORDER = 9,
115
- AAVE_V3_COLLATERAL_SWITCH = 50,
116
- AAVE_V3_DEBT_SWITCH = 55,
117
- AAVE_V3_DEBT_SWITCH_EOA = 56
109
+ AAVE_V3_COLLATERAL_SWITCH = 50
118
110
  }
119
111
  enum Identifiers {
120
112
  SavingsLiqProtection = "smart-savings-liquidation-protection",
@@ -148,8 +140,6 @@ export declare namespace Strategies {
148
140
  EoaRepayOnPrice = "eoa-repay-on-price",
149
141
  CollateralSwitch = "collateral-switch",
150
142
  EoaCollateralSwitch = "eoa-collateral-switch",
151
- DebtSwitch = "debt-switch",
152
- EoaDebtSwitch = "eoa-debt-switch",
153
143
  LiquidationProtection = "liquidation-protection",
154
144
  EoaLiquidationProtection = "liquidation-protection-eoa"
155
145
  }
@@ -105,32 +105,24 @@ export var Strategies;
105
105
  MainnetIds[MainnetIds["AAVE_V4_COLLATERAL_SWITCH_EOA"] = 155] = "AAVE_V4_COLLATERAL_SWITCH_EOA";
106
106
  MainnetIds[MainnetIds["SPARK_COLLATERAL_SWITCH"] = 156] = "SPARK_COLLATERAL_SWITCH";
107
107
  MainnetIds[MainnetIds["SPARK_GENERIC_FL_COLLATERAL_SWITCH"] = 167] = "SPARK_GENERIC_FL_COLLATERAL_SWITCH";
108
- MainnetIds[MainnetIds["AAVE_V3_DEBT_SWITCH"] = 168] = "AAVE_V3_DEBT_SWITCH";
109
- MainnetIds[MainnetIds["AAVE_V3_DEBT_SWITCH_EOA"] = 169] = "AAVE_V3_DEBT_SWITCH_EOA";
110
108
  })(MainnetIds = Strategies.MainnetIds || (Strategies.MainnetIds = {}));
111
109
  let OptimismIds;
112
110
  (function (OptimismIds) {
113
111
  OptimismIds[OptimismIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
114
112
  OptimismIds[OptimismIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
115
113
  OptimismIds[OptimismIds["AAVE_V3_COLLATERAL_SWITCH"] = 24] = "AAVE_V3_COLLATERAL_SWITCH";
116
- OptimismIds[OptimismIds["AAVE_V3_DEBT_SWITCH"] = 25] = "AAVE_V3_DEBT_SWITCH";
117
- OptimismIds[OptimismIds["AAVE_V3_DEBT_SWITCH_EOA"] = 26] = "AAVE_V3_DEBT_SWITCH_EOA";
118
114
  })(OptimismIds = Strategies.OptimismIds || (Strategies.OptimismIds = {}));
119
115
  let BaseIds;
120
116
  (function (BaseIds) {
121
117
  BaseIds[BaseIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
122
118
  BaseIds[BaseIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
123
119
  BaseIds[BaseIds["AAVE_V3_COLLATERAL_SWITCH"] = 56] = "AAVE_V3_COLLATERAL_SWITCH";
124
- BaseIds[BaseIds["AAVE_V3_DEBT_SWITCH"] = 61] = "AAVE_V3_DEBT_SWITCH";
125
- BaseIds[BaseIds["AAVE_V3_DEBT_SWITCH_EOA"] = 62] = "AAVE_V3_DEBT_SWITCH_EOA";
126
120
  })(BaseIds = Strategies.BaseIds || (Strategies.BaseIds = {}));
127
121
  let ArbitrumIds;
128
122
  (function (ArbitrumIds) {
129
123
  ArbitrumIds[ArbitrumIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
130
124
  ArbitrumIds[ArbitrumIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
131
125
  ArbitrumIds[ArbitrumIds["AAVE_V3_COLLATERAL_SWITCH"] = 50] = "AAVE_V3_COLLATERAL_SWITCH";
132
- ArbitrumIds[ArbitrumIds["AAVE_V3_DEBT_SWITCH"] = 55] = "AAVE_V3_DEBT_SWITCH";
133
- ArbitrumIds[ArbitrumIds["AAVE_V3_DEBT_SWITCH_EOA"] = 56] = "AAVE_V3_DEBT_SWITCH_EOA";
134
126
  })(ArbitrumIds = Strategies.ArbitrumIds || (Strategies.ArbitrumIds = {}));
135
127
  let Identifiers;
136
128
  (function (Identifiers) {
@@ -165,8 +157,6 @@ export var Strategies;
165
157
  Identifiers["EoaRepayOnPrice"] = "eoa-repay-on-price";
166
158
  Identifiers["CollateralSwitch"] = "collateral-switch";
167
159
  Identifiers["EoaCollateralSwitch"] = "eoa-collateral-switch";
168
- Identifiers["DebtSwitch"] = "debt-switch";
169
- Identifiers["EoaDebtSwitch"] = "eoa-debt-switch";
170
160
  Identifiers["LiquidationProtection"] = "liquidation-protection";
171
161
  Identifiers["EoaLiquidationProtection"] = "liquidation-protection-eoa";
172
162
  })(Identifiers = Strategies.Identifiers || (Strategies.Identifiers = {}));
@@ -1,7 +1,7 @@
1
1
  import type Web3 from 'web3';
2
2
  import type { AbiItem } from 'web3-utils';
3
3
  import type { BaseContract, BlockType } from './contracts/generated/types';
4
- import type { Subscribe, StrategyModel } from './contracts/generated/SubStorage';
4
+ import type { StrategyModel } from './contracts/generated/SubStorage';
5
5
  import type { ChainId, Strategies, Bundles, ProtocolIdentifiers, RatioState, CloseToAssetType } from './enums';
6
6
  export type PlaceholderType = any;
7
7
  export type EthereumAddress = string;
@@ -53,6 +53,21 @@ interface _SubscriptionOptions {
53
53
  unexpiredOnly: boolean;
54
54
  }
55
55
  export type SubscriptionOptions = Partial<_SubscriptionOptions>;
56
+ /** Subscription record as returned by the automation API (GET /v1/subscriptions) */
57
+ export interface ApiSubscriptionRecord {
58
+ id: number;
59
+ wallet: EthereumAddress;
60
+ wallet_type: string;
61
+ is_enabled: boolean;
62
+ is_bundle: boolean;
63
+ strategy_or_bundle_id: number;
64
+ strategy_ids: number[];
65
+ sub_data_hash: string;
66
+ trigger_data: string[];
67
+ sub_data: string[];
68
+ block_number: number;
69
+ additional_triggers: string[] | null;
70
+ }
56
71
  export declare namespace Interfaces {
57
72
  interface ProtocolBase {
58
73
  id: ProtocolIdentifiers.StrategiesAutomation | ProtocolIdentifiers.LegacyAutomation;
@@ -291,10 +306,17 @@ export interface BundlesInfo {
291
306
  [ChainId.Base]: BaseBundleInfo;
292
307
  }
293
308
  export type StrategyOrBundleIds = typeof Strategies.MainnetIds[keyof typeof Strategies.MainnetIds] | typeof Strategies.OptimismIds[keyof typeof Strategies.OptimismIds] | typeof Strategies.ArbitrumIds[keyof typeof Strategies.ArbitrumIds] | typeof Strategies.BaseIds[keyof typeof Strategies.BaseIds] | typeof Bundles.MainnetIds[keyof typeof Bundles.MainnetIds] | typeof Bundles.OptimismIds[keyof typeof Bundles.OptimismIds] | typeof Bundles.ArbitrumIds[keyof typeof Bundles.ArbitrumIds] | typeof Bundles.BaseIds[keyof typeof Bundles.BaseIds];
309
+ /** Fields of the Subscribe event that parsing relies on */
310
+ export interface SubscriptionEventData {
311
+ subId: string;
312
+ proxy: EthereumAddress;
313
+ subHash: string;
314
+ subStruct: StrategyModel.StrategySubStructOutputStruct;
315
+ }
294
316
  export interface ParseData {
295
317
  chainId: ChainId;
296
318
  blockNumber: BlockNumber;
297
- subscriptionEventData: Subscribe['returnValues'];
319
+ subscriptionEventData: SubscriptionEventData;
298
320
  strategiesSubsData: StrategyModel.StoredSubDataStructOutputStruct;
299
321
  }
300
322
  type MapToProtocolVersion<T> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/automation-sdk",
3
- "version": "3.3.21-debt-switch-dev-dev",
3
+ "version": "3.3.21",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -1,7 +1,8 @@
1
1
  import Web3 from 'web3';
2
2
  import { expect } from 'chai';
3
3
 
4
- import {ChainId} from '../../types/enums';
4
+ import { ChainId } from '../../types/enums';
5
+ import type { ApiSubscriptionRecord } from '../../types';
5
6
 
6
7
  import '../../configuration';
7
8
  import StrategiesAutomation from './StrategiesAutomation';
@@ -700,4 +701,67 @@ describe('Feature: StrategiesAutomation.ts', () => {
700
701
  expect(loneBoost?.subId).to.equal(1);
701
702
  });
702
703
  });
704
+
705
+ describe('When testing StrategiesAutomation.parseSubscriptionsFromApi', () => {
706
+ const strategiesAutomation = new StrategiesAutomation({
707
+ chainId: ChainId.Ethereum,
708
+ provider: Web3_1,
709
+ providerFork: null!,
710
+ });
711
+
712
+ const owner = '0x9cB7E19861665366011899d74E75d4F2A419aEeD';
713
+ const subData = [
714
+ '0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
715
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
716
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
717
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
718
+ ];
719
+ // Aave V3 leverage management: repay (bundle 8, ratio under) and boost (bundle 9, ratio over) for the same owner and market
720
+ const repay: ApiSubscriptionRecord = {
721
+ id: 379,
722
+ wallet: owner,
723
+ wallet_type: 'safe',
724
+ is_enabled: true,
725
+ is_bundle: true,
726
+ strategy_or_bundle_id: 8,
727
+ strategy_ids: [34, 35],
728
+ sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
729
+ trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001'],
730
+ sub_data: subData,
731
+ block_number: 18015756,
732
+ additional_triggers: null,
733
+ };
734
+ const boost: ApiSubscriptionRecord = {
735
+ ...repay,
736
+ id: 380,
737
+ is_enabled: false,
738
+ strategy_or_bundle_id: 9,
739
+ sub_data_hash: '0x1111111111111111111111111111111111111111111111111111111111111111',
740
+ trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000000'],
741
+ };
742
+
743
+ it('Given API records should return parsed positions', () => {
744
+ const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost]);
745
+ expect(positions).to.have.length(2);
746
+ expect(positions.map((p) => p?.subId)).to.eql([379, 380]);
747
+ expect(positions.map((p) => p?.isEnabled)).to.eql([true, false]);
748
+ });
749
+
750
+ it('Given mergeSubs option should merge the repay and boost pair', () => {
751
+ const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { mergeSubs: true });
752
+ expect(positions).to.have.length(1);
753
+ expect(positions[0]?.subIds).to.eql([379, 380]);
754
+ expect(positions[0]?.isEnabled).to.equal(true);
755
+ });
756
+
757
+ it('Given enabledOnly option should drop disabled records before parsing', () => {
758
+ const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { enabledOnly: true });
759
+ expect(positions.map((p) => p?.subId)).to.eql([379]);
760
+ });
761
+
762
+ it('Given a record of an unknown strategy should return null for it', () => {
763
+ const positions = strategiesAutomation.parseSubscriptionsFromApi([{ ...repay, strategy_or_bundle_id: 9999 }]);
764
+ expect(positions).to.eql([null]);
765
+ });
766
+ });
703
767
  });
@@ -4,6 +4,7 @@ import type { PastEventOptions } from 'web3-eth-contract';
4
4
  import PromisePool from 'es6-promise-pool';
5
5
  import type {
6
6
  Position, Interfaces, EthereumAddress, SubscriptionOptions, Contract, ParseData, PlaceholderType, BlockNumber,
7
+ ApiSubscriptionRecord,
7
8
  } from '../../types';
8
9
  import type {
9
10
  StrategyModel, Subscribe, SubStorage, UpdateData,
@@ -15,6 +16,7 @@ import { addToObjectIf, isDefined, isUndefined } from '../../services/utils';
15
16
  import { getAbiItem, makeSubStorageContract } from '../../services/contractService';
16
17
  import { getEventsFromContract, multicall } from '../../services/ethereumService';
17
18
  import { parseStrategiesAutomatedPosition } from '../../services/strategiesService';
19
+ import { parseDataFromApiSubscription } from '../../services/apiSubscriptionsService';
18
20
 
19
21
  import Automation from './Automation';
20
22
 
@@ -259,6 +261,21 @@ export default class StrategiesAutomation extends Automation {
259
261
  return this._getSubscriptions(undefined, options);
260
262
  }
261
263
 
264
+ /**
265
+ * @description Parses subscriptions returned by the automation API (GET /v1/subscriptions)
266
+ */
267
+ public parseSubscriptionsFromApi(records: ApiSubscriptionRecord[], options?: SubscriptionOptions): (Position.Automated | null)[] {
268
+ const filtered = options?.enabledOnly ? records.filter((record) => record.is_enabled) : records;
269
+
270
+ let subscriptions = filtered.map((record) => this.getParsedSubscriptions(parseDataFromApiSubscription(record, this.chainId)));
271
+
272
+ if (options?.mergeSubs) {
273
+ subscriptions = this.mergeSubs(subscriptions);
274
+ }
275
+
276
+ return options?.unexpiredOnly ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
277
+ }
278
+
262
279
  public async getSubscriptionsFor(addresses: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]> {
263
280
  return this._getSubscriptions(addresses, options);
264
281
  }
@@ -145,16 +145,6 @@ export const MAINNET_STRATEGIES_INFO: MainnetStrategiesInfo = {
145
145
  strategyId: Strategies.Identifiers.EoaCollateralSwitch,
146
146
  protocol: PROTOCOLS.Spark,
147
147
  },
148
- [Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH]: {
149
- strategyOrBundleId: Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH,
150
- strategyId: Strategies.Identifiers.DebtSwitch,
151
- protocol: PROTOCOLS.AaveV3,
152
- },
153
- [Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH_EOA]: {
154
- strategyOrBundleId: Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH_EOA,
155
- strategyId: Strategies.Identifiers.EoaDebtSwitch,
156
- protocol: PROTOCOLS.AaveV3,
157
- },
158
148
  };
159
149
 
160
150
  export const OPTIMISM_STRATEGIES_INFO: OptimismStrategiesInfo = {
@@ -173,16 +163,6 @@ export const OPTIMISM_STRATEGIES_INFO: OptimismStrategiesInfo = {
173
163
  strategyId: Strategies.Identifiers.CollateralSwitch,
174
164
  protocol: PROTOCOLS.AaveV3,
175
165
  },
176
- [Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH]: {
177
- strategyOrBundleId: Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH,
178
- strategyId: Strategies.Identifiers.DebtSwitch,
179
- protocol: PROTOCOLS.AaveV3,
180
- },
181
- [Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH_EOA]: {
182
- strategyOrBundleId: Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH_EOA,
183
- strategyId: Strategies.Identifiers.EoaDebtSwitch,
184
- protocol: PROTOCOLS.AaveV3,
185
- },
186
166
  };
187
167
 
188
168
  export const BASE_STRATEGIES_INFO: BaseStrategiesInfo = {
@@ -201,16 +181,6 @@ export const BASE_STRATEGIES_INFO: BaseStrategiesInfo = {
201
181
  strategyId: Strategies.Identifiers.CollateralSwitch,
202
182
  protocol: PROTOCOLS.AaveV3,
203
183
  },
204
- [Strategies.BaseIds.AAVE_V3_DEBT_SWITCH]: {
205
- strategyOrBundleId: Strategies.BaseIds.AAVE_V3_DEBT_SWITCH,
206
- strategyId: Strategies.Identifiers.DebtSwitch,
207
- protocol: PROTOCOLS.AaveV3,
208
- },
209
- [Strategies.BaseIds.AAVE_V3_DEBT_SWITCH_EOA]: {
210
- strategyOrBundleId: Strategies.BaseIds.AAVE_V3_DEBT_SWITCH_EOA,
211
- strategyId: Strategies.Identifiers.EoaDebtSwitch,
212
- protocol: PROTOCOLS.AaveV3,
213
- },
214
184
  };
215
185
 
216
186
  export const ARBITRUM_STRATEGIES_INFO: ArbitrumStrategiesInfo = {
@@ -229,16 +199,6 @@ export const ARBITRUM_STRATEGIES_INFO: ArbitrumStrategiesInfo = {
229
199
  strategyId: Strategies.Identifiers.CollateralSwitch,
230
200
  protocol: PROTOCOLS.AaveV3,
231
201
  },
232
- [Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH]: {
233
- strategyOrBundleId: Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH,
234
- strategyId: Strategies.Identifiers.DebtSwitch,
235
- protocol: PROTOCOLS.AaveV3,
236
- },
237
- [Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH_EOA]: {
238
- strategyOrBundleId: Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH_EOA,
239
- strategyId: Strategies.Identifiers.EoaDebtSwitch,
240
- protocol: PROTOCOLS.AaveV3,
241
- },
242
202
  };
243
203
 
244
204
  export const STRATEGIES_INFO: StrategiesInfo = {
@@ -0,0 +1,73 @@
1
+ import { expect } from 'chai';
2
+
3
+ import type { ApiSubscriptionRecord, ParseData } from '../types';
4
+ import { ChainId } from '../types/enums';
5
+
6
+ import '../configuration';
7
+ import { parseDataFromApiSubscription } from './apiSubscriptionsService';
8
+ import { parseStrategiesAutomatedPosition } from './strategiesService';
9
+
10
+ describe('Feature: apiSubscriptionsService.ts', () => {
11
+ describe('When testing apiSubscriptionsService.parseDataFromApiSubscription', () => {
12
+ // same subscription as in strategiesService.test.ts, in the shape the automation API returns it
13
+ const record: ApiSubscriptionRecord = {
14
+ id: 379,
15
+ wallet: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
16
+ wallet_type: 'safe',
17
+ is_enabled: true,
18
+ is_bundle: true,
19
+ strategy_or_bundle_id: 8,
20
+ strategy_ids: [34, 35],
21
+ sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
22
+ trigger_data: [
23
+ '0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
24
+ ],
25
+ sub_data: [
26
+ '0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
27
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
28
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
29
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
30
+ ],
31
+ block_number: 18015756,
32
+ additional_triggers: null,
33
+ };
34
+
35
+ const fromEvents: ParseData = {
36
+ chainId: ChainId.Ethereum,
37
+ blockNumber: 18015756,
38
+ subscriptionEventData: {
39
+ subId: '379',
40
+ proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
41
+ subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
42
+ subStruct: {
43
+ strategyOrBundleId: '8',
44
+ isBundle: true,
45
+ triggerData: [
46
+ '0x0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
47
+ ],
48
+ subData: record.sub_data,
49
+ },
50
+ },
51
+ strategiesSubsData: {
52
+ userProxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
53
+ isEnabled: true,
54
+ strategySubHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
55
+ },
56
+ };
57
+
58
+ it('Given an API record should return the same parse data as Subscribe event and SubStorage would', () => {
59
+ expect(parseDataFromApiSubscription(record, ChainId.Ethereum)).to.eql(fromEvents);
60
+ });
61
+
62
+ it('Given an API record the parsed position should match the one parsed from events', () => {
63
+ const fromApi = parseStrategiesAutomatedPosition(parseDataFromApiSubscription(record, ChainId.Ethereum));
64
+ expect(fromApi).to.not.equal(null);
65
+ expect(fromApi).to.eql(parseStrategiesAutomatedPosition(fromEvents));
66
+ });
67
+
68
+ it('Given a disabled record should keep it disabled', () => {
69
+ const parseData = parseDataFromApiSubscription({ ...record, is_enabled: false }, ChainId.Ethereum);
70
+ expect(parseData.strategiesSubsData.isEnabled).to.equal(false);
71
+ });
72
+ });
73
+ });
@@ -0,0 +1,33 @@
1
+ import type { ApiSubscriptionRecord, ParseData } from '../types';
2
+ import type { ChainId } from '../types/enums';
3
+
4
+ function addHexPrefix(value: string): string {
5
+ return value.startsWith('0x') ? value : `0x${value}`;
6
+ }
7
+
8
+ /**
9
+ * @description Maps a subscription record returned by the automation API to the data
10
+ * the parser expects from Subscribe events and SubStorage (trigger data is stored without 0x prefix)
11
+ */
12
+ export function parseDataFromApiSubscription(record: ApiSubscriptionRecord, chainId: ChainId): ParseData {
13
+ return {
14
+ chainId,
15
+ blockNumber: record.block_number,
16
+ subscriptionEventData: {
17
+ subId: record.id.toString(),
18
+ proxy: record.wallet,
19
+ subHash: record.sub_data_hash,
20
+ subStruct: {
21
+ strategyOrBundleId: record.strategy_or_bundle_id.toString(),
22
+ isBundle: record.is_bundle,
23
+ triggerData: record.trigger_data.map(addHexPrefix),
24
+ subData: record.sub_data.map(addHexPrefix),
25
+ },
26
+ },
27
+ strategiesSubsData: {
28
+ userProxy: record.wallet,
29
+ isEnabled: record.is_enabled,
30
+ strategySubHash: record.sub_data_hash,
31
+ },
32
+ };
33
+ }
@@ -76,7 +76,6 @@ describe('Feature: strategiesService.ts', () => {
76
76
  subId: '379',
77
77
  proxy: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
78
78
  subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
79
- // @ts-ignore
80
79
  subStruct:
81
80
  {
82
81
  strategyOrBundleId: '8',
@@ -445,19 +445,6 @@ function parseAaveV3CollateralSwitch(position: Position.Automated, parseData: Pa
445
445
  return _position;
446
446
  }
447
447
 
448
- function parseAaveV3DebtSwitch(position: Position.Automated, parseData: ParseData): Position.Automated {
449
- const _position = cloneDeep(position);
450
- const { subStruct } = parseData.subscriptionEventData;
451
- const triggerData = triggerService.aaveV3QuotePriceTrigger.decode(subStruct.triggerData);
452
- const subData = subDataService.aaveV3DebtSwitchSubData.decode(subStruct.subData);
453
- _position.strategyData.decoded.triggerData = triggerData;
454
- _position.strategyData.decoded.subData = subData;
455
- // TODO -> This isn't enough for ID
456
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.marketAddr);
457
-
458
- return _position;
459
- }
460
-
461
448
  function parseSparkCollateralSwitch(position: Position.Automated, parseData: ParseData): Position.Automated {
462
449
  const _position = cloneDeep(position);
463
450
  const { subStruct } = parseData.subscriptionEventData;
@@ -1610,8 +1597,6 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
1610
1597
  [Strategies.Identifiers.EoaBoostOnPrice]: parseAaveV3LeverageManagementOnPrice,
1611
1598
  [Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV3CloseOnPrice,
1612
1599
  [Strategies.Identifiers.CollateralSwitch]: parseAaveV3CollateralSwitch,
1613
- [Strategies.Identifiers.DebtSwitch]: parseAaveV3DebtSwitch,
1614
- [Strategies.Identifiers.EoaDebtSwitch]: parseAaveV3DebtSwitch,
1615
1600
  [Strategies.Identifiers.LiquidationProtection]: parseAaveV3LiquidationProtection,
1616
1601
  [Strategies.Identifiers.EoaLiquidationProtection]: parseAaveV3LiquidationProtection,
1617
1602
  },