@defisaver/automation-sdk 3.3.21-instant-twap-close-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.
- package/cjs/automation/private/StrategiesAutomation.d.ts +5 -1
- package/cjs/automation/private/StrategiesAutomation.js +12 -0
- package/cjs/automation/private/StrategiesAutomation.test.js +51 -0
- package/cjs/constants/index.js +0 -10
- package/cjs/services/apiSubscriptionsService.d.ts +7 -0
- package/cjs/services/apiSubscriptionsService.js +33 -0
- package/cjs/services/apiSubscriptionsService.test.d.ts +1 -0
- package/cjs/services/apiSubscriptionsService.test.js +67 -0
- package/cjs/services/strategiesService.js +0 -25
- package/cjs/services/strategiesService.test.js +0 -63
- package/cjs/services/strategySubService.d.ts +0 -1
- package/cjs/services/strategySubService.js +0 -7
- package/cjs/services/strategySubService.test.js +0 -111
- package/cjs/services/subDataService.d.ts +0 -14
- package/cjs/services/subDataService.js +2 -40
- package/cjs/services/subDataService.test.js +0 -70
- package/cjs/types/enums.d.ts +1 -5
- package/cjs/types/enums.js +0 -4
- package/cjs/types/index.d.ts +24 -2
- package/esm/automation/private/StrategiesAutomation.d.ts +5 -1
- package/esm/automation/private/StrategiesAutomation.js +12 -0
- package/esm/automation/private/StrategiesAutomation.test.js +51 -0
- package/esm/constants/index.js +0 -10
- package/esm/services/apiSubscriptionsService.d.ts +7 -0
- package/esm/services/apiSubscriptionsService.js +29 -0
- package/esm/services/apiSubscriptionsService.test.d.ts +1 -0
- package/esm/services/apiSubscriptionsService.test.js +65 -0
- package/esm/services/strategiesService.js +0 -25
- package/esm/services/strategiesService.test.js +1 -64
- package/esm/services/strategySubService.d.ts +0 -1
- package/esm/services/strategySubService.js +0 -7
- package/esm/services/strategySubService.test.js +0 -111
- package/esm/services/subDataService.d.ts +0 -14
- package/esm/services/subDataService.js +0 -38
- package/esm/services/subDataService.test.js +0 -70
- package/esm/types/enums.d.ts +1 -5
- package/esm/types/enums.js +0 -4
- package/esm/types/index.d.ts +24 -2
- package/package.json +1 -1
- package/src/automation/private/StrategiesAutomation.test.ts +65 -1
- package/src/automation/private/StrategiesAutomation.ts +17 -0
- package/src/constants/index.ts +0 -10
- package/src/services/apiSubscriptionsService.test.ts +73 -0
- package/src/services/apiSubscriptionsService.ts +33 -0
- package/src/services/strategiesService.test.ts +1 -79
- package/src/services/strategiesService.ts +0 -33
- package/src/services/strategySubService.test.ts +0 -130
- package/src/services/strategySubService.ts +0 -26
- package/src/services/subDataService.test.ts +0 -98
- package/src/services/subDataService.ts +0 -61
- package/src/types/enums.ts +0 -4
- package/src/types/index.ts +26 -2
|
@@ -2281,76 +2281,6 @@ describe('Feature: subDataService.ts', () => {
|
|
|
2281
2281
|
});
|
|
2282
2282
|
});
|
|
2283
2283
|
});
|
|
2284
|
-
describe("When testing subDataService.aaveV3InstantCloseGenericSubData", () => {
|
|
2285
|
-
const WETH = web3Utils.toChecksumAddress((0, tokens_1.getAssetInfo)('WETH', enums_1.ChainId.Ethereum).address);
|
|
2286
|
-
const USDC = web3Utils.toChecksumAddress((0, tokens_1.getAssetInfo)('USDC', enums_1.ChainId.Ethereum).address);
|
|
2287
|
-
const MARKET = web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39');
|
|
2288
|
-
const USER = web3Utils.toChecksumAddress('0x1234567890123456789012345678901234567890');
|
|
2289
|
-
const examples = [
|
|
2290
|
-
// TAKE_PROFIT_IN_COLLATERAL, zero tsi and slippage
|
|
2291
|
-
[
|
|
2292
|
-
[
|
|
2293
|
-
'0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
|
2294
|
-
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
2295
|
-
'0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
2296
|
-
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
2297
|
-
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
2298
|
-
'0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
|
|
2299
|
-
'0x0000000000000000000000001234567890123456789012345678901234567890',
|
|
2300
|
-
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
2301
|
-
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
2302
|
-
],
|
|
2303
|
-
[WETH, 0, USDC, 1, enums_1.CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL, MARKET, USER, '0', '0'],
|
|
2304
|
-
],
|
|
2305
|
-
// STOP_LOSS_IN_DEBT
|
|
2306
|
-
[
|
|
2307
|
-
[
|
|
2308
|
-
'0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
|
2309
|
-
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
2310
|
-
'0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
2311
|
-
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
2312
|
-
'0x0000000000000000000000000000000000000000000000000000000000000003',
|
|
2313
|
-
'0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
|
|
2314
|
-
'0x0000000000000000000000001234567890123456789012345678901234567890',
|
|
2315
|
-
'0x0000000000000000000000000000000000000000000000000de0b6b3a7640000',
|
|
2316
|
-
'0x000000000000000000000000000000000000000000000000002386f26fc10000',
|
|
2317
|
-
],
|
|
2318
|
-
[WETH, 0, USDC, 1, enums_1.CloseStrategyType.STOP_LOSS_IN_DEBT, MARKET, USER, '1000000000000000000', '10000000000000000'],
|
|
2319
|
-
],
|
|
2320
|
-
// TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL, asset ids above uint8 range
|
|
2321
|
-
[
|
|
2322
|
-
[
|
|
2323
|
-
'0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
|
2324
|
-
'0x000000000000000000000000000000000000000000000000000000000000012c',
|
|
2325
|
-
'0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
2326
|
-
'0x0000000000000000000000000000000000000000000000000000000000000190',
|
|
2327
|
-
'0x0000000000000000000000000000000000000000000000000000000000000007',
|
|
2328
|
-
'0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
|
|
2329
|
-
'0x0000000000000000000000001234567890123456789012345678901234567890',
|
|
2330
|
-
'0x00000000000000000000000000000000000000000000000000b1a2bc2ec50000',
|
|
2331
|
-
'0x0000000000000000000000000000000000000000000000000011c37937e08000',
|
|
2332
|
-
],
|
|
2333
|
-
[WETH, 300, USDC, 400, enums_1.CloseStrategyType.TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL, MARKET, USER, '50000000000000000', '5000000000000000'],
|
|
2334
|
-
],
|
|
2335
|
-
];
|
|
2336
|
-
describe("encode()", () => {
|
|
2337
|
-
examples.forEach(([expected, actual]) => {
|
|
2338
|
-
it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
|
|
2339
|
-
(0, chai_1.expect)(subDataService.aaveV3InstantCloseGenericSubData.encode(...actual)).to.eql(expected);
|
|
2340
|
-
});
|
|
2341
|
-
});
|
|
2342
|
-
});
|
|
2343
|
-
describe("decode()", () => {
|
|
2344
|
-
examples.forEach(([encoded, [collAsset, collAssetId, debtAsset, debtAssetId, closeType, marketAddr, user, tsi, slippage]]) => {
|
|
2345
|
-
const expected = {
|
|
2346
|
-
collAsset, collAssetId, debtAsset, debtAssetId, closeType, marketAddr, owner: user, tsi, slippage,
|
|
2347
|
-
};
|
|
2348
|
-
it(`Given ${JSON.stringify(encoded)} should return expected value: ${JSON.stringify(expected)}`, () => {
|
|
2349
|
-
(0, chai_1.expect)(subDataService.aaveV3InstantCloseGenericSubData.decode(encoded)).to.eql(expected);
|
|
2350
|
-
});
|
|
2351
|
-
});
|
|
2352
|
-
});
|
|
2353
|
-
});
|
|
2354
2284
|
describe('When testing subDataService.sparkLeverageManagementOnPriceSubData', () => {
|
|
2355
2285
|
describe('encode()', () => {
|
|
2356
2286
|
const examples = [
|
package/cjs/types/enums.d.ts
CHANGED
|
@@ -124,8 +124,6 @@ export declare namespace Strategies {
|
|
|
124
124
|
CloseOnPriceToColl = "close-on-price-to-collateral",
|
|
125
125
|
CloseOnPrice = "close-on-price",
|
|
126
126
|
EoaCloseOnPrice = "eoa-close-on-price",
|
|
127
|
-
InstantCloseOnPrice = "instant-close-on-price",
|
|
128
|
-
EoaInstantCloseOnPrice = "eoa-instant-close-on-price",
|
|
129
127
|
TrailingStopToColl = "trailing-stop-to-collateral",
|
|
130
128
|
TrailingStopToDebt = "trailing-stop-to-debt",
|
|
131
129
|
Rebond = "rebond",
|
|
@@ -252,9 +250,7 @@ export declare namespace Bundles {
|
|
|
252
250
|
SPARK_EOA_REPAY_ON_PRICE = 90,
|
|
253
251
|
SPARK_EOA_BOOST_ON_PRICE = 91,
|
|
254
252
|
SPARK_EOA_CLOSE = 92,
|
|
255
|
-
SPARK_EOA_LIQUIDATION_PROTECTION = 93
|
|
256
|
-
AAVE_V3_SW_INSTANT_CLOSE = 94,
|
|
257
|
-
AAVE_V3_EOA_INSTANT_CLOSE = 95
|
|
253
|
+
SPARK_EOA_LIQUIDATION_PROTECTION = 93
|
|
258
254
|
}
|
|
259
255
|
enum OptimismIds {
|
|
260
256
|
AAVE_V3_REPAY = 0,
|
package/cjs/types/enums.js
CHANGED
|
@@ -144,8 +144,6 @@ var Strategies;
|
|
|
144
144
|
Identifiers["CloseOnPriceToColl"] = "close-on-price-to-collateral";
|
|
145
145
|
Identifiers["CloseOnPrice"] = "close-on-price";
|
|
146
146
|
Identifiers["EoaCloseOnPrice"] = "eoa-close-on-price";
|
|
147
|
-
Identifiers["InstantCloseOnPrice"] = "instant-close-on-price";
|
|
148
|
-
Identifiers["EoaInstantCloseOnPrice"] = "eoa-instant-close-on-price";
|
|
149
147
|
Identifiers["TrailingStopToColl"] = "trailing-stop-to-collateral";
|
|
150
148
|
Identifiers["TrailingStopToDebt"] = "trailing-stop-to-debt";
|
|
151
149
|
Identifiers["Rebond"] = "rebond";
|
|
@@ -276,8 +274,6 @@ var Bundles;
|
|
|
276
274
|
MainnetIds[MainnetIds["SPARK_EOA_BOOST_ON_PRICE"] = 91] = "SPARK_EOA_BOOST_ON_PRICE";
|
|
277
275
|
MainnetIds[MainnetIds["SPARK_EOA_CLOSE"] = 92] = "SPARK_EOA_CLOSE";
|
|
278
276
|
MainnetIds[MainnetIds["SPARK_EOA_LIQUIDATION_PROTECTION"] = 93] = "SPARK_EOA_LIQUIDATION_PROTECTION";
|
|
279
|
-
MainnetIds[MainnetIds["AAVE_V3_SW_INSTANT_CLOSE"] = 94] = "AAVE_V3_SW_INSTANT_CLOSE";
|
|
280
|
-
MainnetIds[MainnetIds["AAVE_V3_EOA_INSTANT_CLOSE"] = 95] = "AAVE_V3_EOA_INSTANT_CLOSE";
|
|
281
277
|
})(MainnetIds = Bundles.MainnetIds || (Bundles.MainnetIds = {}));
|
|
282
278
|
let OptimismIds;
|
|
283
279
|
(function (OptimismIds) {
|
package/cjs/types/index.d.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
319
|
+
subscriptionEventData: SubscriptionEventData;
|
|
298
320
|
strategiesSubsData: StrategyModel.StoredSubDataStructOutputStruct;
|
|
299
321
|
}
|
|
300
322
|
type MapToProtocolVersion<T> = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type Web3 from 'web3';
|
|
2
2
|
import type { PastEventOptions } from 'web3-eth-contract';
|
|
3
|
-
import type { Position, Interfaces, EthereumAddress, SubscriptionOptions, Contract, ParseData, BlockNumber } from '../../types';
|
|
3
|
+
import type { Position, Interfaces, EthereumAddress, SubscriptionOptions, Contract, ParseData, BlockNumber, ApiSubscriptionRecord } from '../../types';
|
|
4
4
|
import type { StrategyModel, Subscribe, SubStorage, UpdateData } from '../../types/contracts/generated/SubStorage';
|
|
5
5
|
import type { ChainId } from '../../types/enums';
|
|
6
6
|
import Automation from './Automation';
|
|
@@ -30,6 +30,10 @@ export default class StrategiesAutomation extends Automation {
|
|
|
30
30
|
protected mergeSubs(_subscriptions: (Position.Automated | null)[]): Position.Automated[];
|
|
31
31
|
protected _getSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
|
|
32
32
|
getSubscriptions(options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
|
|
33
|
+
/**
|
|
34
|
+
* @description Parses subscriptions returned by the automation API (GET /v1/subscriptions)
|
|
35
|
+
*/
|
|
36
|
+
parseSubscriptionsFromApi(records: ApiSubscriptionRecord[], options?: SubscriptionOptions): (Position.Automated | null)[];
|
|
33
37
|
getSubscriptionsFor(addresses: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
|
|
34
38
|
}
|
|
35
39
|
export {};
|
|
@@ -14,6 +14,7 @@ import { addToObjectIf, isDefined, isUndefined } from '../../services/utils';
|
|
|
14
14
|
import { getAbiItem, makeSubStorageContract } from '../../services/contractService';
|
|
15
15
|
import { getEventsFromContract, multicall } from '../../services/ethereumService';
|
|
16
16
|
import { parseStrategiesAutomatedPosition } from '../../services/strategiesService';
|
|
17
|
+
import { parseDataFromApiSubscription } from '../../services/apiSubscriptionsService';
|
|
17
18
|
import Automation from './Automation';
|
|
18
19
|
export default class StrategiesAutomation extends Automation {
|
|
19
20
|
constructor(args) {
|
|
@@ -184,6 +185,17 @@ export default class StrategiesAutomation extends Automation {
|
|
|
184
185
|
return this._getSubscriptions(undefined, options);
|
|
185
186
|
});
|
|
186
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* @description Parses subscriptions returned by the automation API (GET /v1/subscriptions)
|
|
190
|
+
*/
|
|
191
|
+
parseSubscriptionsFromApi(records, options) {
|
|
192
|
+
const filtered = (options === null || options === void 0 ? void 0 : options.enabledOnly) ? records.filter((record) => record.is_enabled) : records;
|
|
193
|
+
let subscriptions = filtered.map((record) => this.getParsedSubscriptions(parseDataFromApiSubscription(record, this.chainId)));
|
|
194
|
+
if (options === null || options === void 0 ? void 0 : options.mergeSubs) {
|
|
195
|
+
subscriptions = this.mergeSubs(subscriptions);
|
|
196
|
+
}
|
|
197
|
+
return (options === null || options === void 0 ? void 0 : options.unexpiredOnly) ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
|
|
198
|
+
}
|
|
187
199
|
getSubscriptionsFor(addresses, options) {
|
|
188
200
|
return __awaiter(this, void 0, void 0, function* () {
|
|
189
201
|
return this._getSubscriptions(addresses, options);
|
|
@@ -688,4 +688,55 @@ describe('Feature: StrategiesAutomation.ts', () => {
|
|
|
688
688
|
expect(loneBoost === null || loneBoost === void 0 ? void 0 : loneBoost.subId).to.equal(1);
|
|
689
689
|
});
|
|
690
690
|
}));
|
|
691
|
+
describe('When testing StrategiesAutomation.parseSubscriptionsFromApi', () => {
|
|
692
|
+
const strategiesAutomation = new StrategiesAutomation({
|
|
693
|
+
chainId: ChainId.Ethereum,
|
|
694
|
+
provider: Web3_1,
|
|
695
|
+
providerFork: null,
|
|
696
|
+
});
|
|
697
|
+
const owner = '0x9cB7E19861665366011899d74E75d4F2A419aEeD';
|
|
698
|
+
const subData = [
|
|
699
|
+
'0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
|
|
700
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
701
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
702
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
703
|
+
];
|
|
704
|
+
// Aave V3 leverage management: repay (bundle 8, ratio under) and boost (bundle 9, ratio over) for the same owner and market
|
|
705
|
+
const repay = {
|
|
706
|
+
id: 379,
|
|
707
|
+
wallet: owner,
|
|
708
|
+
wallet_type: 'safe',
|
|
709
|
+
is_enabled: true,
|
|
710
|
+
is_bundle: true,
|
|
711
|
+
strategy_or_bundle_id: 8,
|
|
712
|
+
strategy_ids: [34, 35],
|
|
713
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
714
|
+
trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001'],
|
|
715
|
+
sub_data: subData,
|
|
716
|
+
block_number: 18015756,
|
|
717
|
+
additional_triggers: null,
|
|
718
|
+
};
|
|
719
|
+
const boost = Object.assign(Object.assign({}, repay), { id: 380, is_enabled: false, strategy_or_bundle_id: 9, sub_data_hash: '0x1111111111111111111111111111111111111111111111111111111111111111', trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000000'] });
|
|
720
|
+
it('Given API records should return parsed positions', () => {
|
|
721
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost]);
|
|
722
|
+
expect(positions).to.have.length(2);
|
|
723
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.subId)).to.eql([379, 380]);
|
|
724
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.isEnabled)).to.eql([true, false]);
|
|
725
|
+
});
|
|
726
|
+
it('Given mergeSubs option should merge the repay and boost pair', () => {
|
|
727
|
+
var _a, _b;
|
|
728
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { mergeSubs: true });
|
|
729
|
+
expect(positions).to.have.length(1);
|
|
730
|
+
expect((_a = positions[0]) === null || _a === void 0 ? void 0 : _a.subIds).to.eql([379, 380]);
|
|
731
|
+
expect((_b = positions[0]) === null || _b === void 0 ? void 0 : _b.isEnabled).to.equal(true);
|
|
732
|
+
});
|
|
733
|
+
it('Given enabledOnly option should drop disabled records before parsing', () => {
|
|
734
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { enabledOnly: true });
|
|
735
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.subId)).to.eql([379]);
|
|
736
|
+
});
|
|
737
|
+
it('Given a record of an unknown strategy should return null for it', () => {
|
|
738
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([Object.assign(Object.assign({}, repay), { strategy_or_bundle_id: 9999 })]);
|
|
739
|
+
expect(positions).to.eql([null]);
|
|
740
|
+
});
|
|
741
|
+
});
|
|
691
742
|
});
|
package/esm/constants/index.js
CHANGED
|
@@ -653,16 +653,6 @@ export const MAINNET_BUNDLES_INFO = {
|
|
|
653
653
|
strategyId: Strategies.Identifiers.EoaLiquidationProtection,
|
|
654
654
|
protocol: PROTOCOLS.Spark,
|
|
655
655
|
},
|
|
656
|
-
[Bundles.MainnetIds.AAVE_V3_SW_INSTANT_CLOSE]: {
|
|
657
|
-
strategyOrBundleId: Bundles.MainnetIds.AAVE_V3_SW_INSTANT_CLOSE,
|
|
658
|
-
strategyId: Strategies.Identifiers.InstantCloseOnPrice,
|
|
659
|
-
protocol: PROTOCOLS.AaveV3,
|
|
660
|
-
},
|
|
661
|
-
[Bundles.MainnetIds.AAVE_V3_EOA_INSTANT_CLOSE]: {
|
|
662
|
-
strategyOrBundleId: Bundles.MainnetIds.AAVE_V3_EOA_INSTANT_CLOSE,
|
|
663
|
-
strategyId: Strategies.Identifiers.EoaInstantCloseOnPrice,
|
|
664
|
-
protocol: PROTOCOLS.AaveV3,
|
|
665
|
-
},
|
|
666
656
|
};
|
|
667
657
|
export const OPTIMISM_BUNDLES_INFO = {
|
|
668
658
|
[Bundles.OptimismIds.AAVE_V3_REPAY]: {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ApiSubscriptionRecord, ParseData } from '../types';
|
|
2
|
+
import type { ChainId } from '../types/enums';
|
|
3
|
+
/**
|
|
4
|
+
* @description Maps a subscription record returned by the automation API to the data
|
|
5
|
+
* the parser expects from Subscribe events and SubStorage (trigger data is stored without 0x prefix)
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseDataFromApiSubscription(record: ApiSubscriptionRecord, chainId: ChainId): ParseData;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function addHexPrefix(value) {
|
|
2
|
+
return value.startsWith('0x') ? value : `0x${value}`;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* @description Maps a subscription record returned by the automation API to the data
|
|
6
|
+
* the parser expects from Subscribe events and SubStorage (trigger data is stored without 0x prefix)
|
|
7
|
+
*/
|
|
8
|
+
export function parseDataFromApiSubscription(record, chainId) {
|
|
9
|
+
return {
|
|
10
|
+
chainId,
|
|
11
|
+
blockNumber: record.block_number,
|
|
12
|
+
subscriptionEventData: {
|
|
13
|
+
subId: record.id.toString(),
|
|
14
|
+
proxy: record.wallet,
|
|
15
|
+
subHash: record.sub_data_hash,
|
|
16
|
+
subStruct: {
|
|
17
|
+
strategyOrBundleId: record.strategy_or_bundle_id.toString(),
|
|
18
|
+
isBundle: record.is_bundle,
|
|
19
|
+
triggerData: record.trigger_data.map(addHexPrefix),
|
|
20
|
+
subData: record.sub_data.map(addHexPrefix),
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
strategiesSubsData: {
|
|
24
|
+
userProxy: record.wallet,
|
|
25
|
+
isEnabled: record.is_enabled,
|
|
26
|
+
strategySubHash: record.sub_data_hash,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../configuration';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { ChainId } from '../types/enums';
|
|
3
|
+
import '../configuration';
|
|
4
|
+
import { parseDataFromApiSubscription } from './apiSubscriptionsService';
|
|
5
|
+
import { parseStrategiesAutomatedPosition } from './strategiesService';
|
|
6
|
+
describe('Feature: apiSubscriptionsService.ts', () => {
|
|
7
|
+
describe('When testing apiSubscriptionsService.parseDataFromApiSubscription', () => {
|
|
8
|
+
// same subscription as in strategiesService.test.ts, in the shape the automation API returns it
|
|
9
|
+
const record = {
|
|
10
|
+
id: 379,
|
|
11
|
+
wallet: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
12
|
+
wallet_type: 'safe',
|
|
13
|
+
is_enabled: true,
|
|
14
|
+
is_bundle: true,
|
|
15
|
+
strategy_or_bundle_id: 8,
|
|
16
|
+
strategy_ids: [34, 35],
|
|
17
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
18
|
+
trigger_data: [
|
|
19
|
+
'0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
20
|
+
],
|
|
21
|
+
sub_data: [
|
|
22
|
+
'0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
|
|
23
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
24
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
25
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
26
|
+
],
|
|
27
|
+
block_number: 18015756,
|
|
28
|
+
additional_triggers: null,
|
|
29
|
+
};
|
|
30
|
+
const fromEvents = {
|
|
31
|
+
chainId: ChainId.Ethereum,
|
|
32
|
+
blockNumber: 18015756,
|
|
33
|
+
subscriptionEventData: {
|
|
34
|
+
subId: '379',
|
|
35
|
+
proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
36
|
+
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
37
|
+
subStruct: {
|
|
38
|
+
strategyOrBundleId: '8',
|
|
39
|
+
isBundle: true,
|
|
40
|
+
triggerData: [
|
|
41
|
+
'0x0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
42
|
+
],
|
|
43
|
+
subData: record.sub_data,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
strategiesSubsData: {
|
|
47
|
+
userProxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
48
|
+
isEnabled: true,
|
|
49
|
+
strategySubHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
it('Given an API record should return the same parse data as Subscribe event and SubStorage would', () => {
|
|
53
|
+
expect(parseDataFromApiSubscription(record, ChainId.Ethereum)).to.eql(fromEvents);
|
|
54
|
+
});
|
|
55
|
+
it('Given an API record the parsed position should match the one parsed from events', () => {
|
|
56
|
+
const fromApi = parseStrategiesAutomatedPosition(parseDataFromApiSubscription(record, ChainId.Ethereum));
|
|
57
|
+
expect(fromApi).to.not.equal(null);
|
|
58
|
+
expect(fromApi).to.eql(parseStrategiesAutomatedPosition(fromEvents));
|
|
59
|
+
});
|
|
60
|
+
it('Given a disabled record should keep it disabled', () => {
|
|
61
|
+
const parseData = parseDataFromApiSubscription(Object.assign(Object.assign({}, record), { is_enabled: false }), ChainId.Ethereum);
|
|
62
|
+
expect(parseData.strategiesSubsData.isEnabled).to.equal(false);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -317,29 +317,6 @@ function parseAaveV3CloseOnPrice(position, parseData) {
|
|
|
317
317
|
}
|
|
318
318
|
return _position;
|
|
319
319
|
}
|
|
320
|
-
function parseAaveV3InstantCloseOnPrice(position, parseData) {
|
|
321
|
-
const _position = cloneDeep(position);
|
|
322
|
-
const { subStruct } = parseData.subscriptionEventData;
|
|
323
|
-
const triggerData = triggerService.aaveV3QuotePriceRangeTrigger.decode(subStruct.triggerData);
|
|
324
|
-
const subData = subDataService.aaveV3InstantCloseGenericSubData.decode(subStruct.subData);
|
|
325
|
-
const { takeProfitType, stopLossType } = getStopLossAndTakeProfitTypeByCloseStrategyType(+subData.closeType);
|
|
326
|
-
_position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
|
|
327
|
-
_position.strategyData.decoded.triggerData = triggerData;
|
|
328
|
-
_position.strategyData.decoded.subData = subData;
|
|
329
|
-
_position.specific = {
|
|
330
|
-
collAsset: subData.collAsset,
|
|
331
|
-
collAssetId: subData.collAssetId,
|
|
332
|
-
debtAsset: subData.debtAsset,
|
|
333
|
-
debtAssetId: subData.debtAssetId,
|
|
334
|
-
baseToken: triggerData.collToken,
|
|
335
|
-
quoteToken: triggerData.debtToken,
|
|
336
|
-
stopLossPrice: triggerData.lowerPrice,
|
|
337
|
-
takeProfitPrice: triggerData.upperPrice,
|
|
338
|
-
stopLossType,
|
|
339
|
-
takeProfitType,
|
|
340
|
-
};
|
|
341
|
-
return _position;
|
|
342
|
-
}
|
|
343
320
|
function parseAaveV3CollateralSwitch(position, parseData) {
|
|
344
321
|
const _position = cloneDeep(position);
|
|
345
322
|
const { subStruct } = parseData.subscriptionEventData;
|
|
@@ -1239,8 +1216,6 @@ const parsingMethodsMapping = {
|
|
|
1239
1216
|
[Strategies.Identifiers.EoaRepayOnPrice]: parseAaveV3LeverageManagementOnPrice,
|
|
1240
1217
|
[Strategies.Identifiers.EoaBoostOnPrice]: parseAaveV3LeverageManagementOnPrice,
|
|
1241
1218
|
[Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV3CloseOnPrice,
|
|
1242
|
-
[Strategies.Identifiers.InstantCloseOnPrice]: parseAaveV3InstantCloseOnPrice,
|
|
1243
|
-
[Strategies.Identifiers.EoaInstantCloseOnPrice]: parseAaveV3InstantCloseOnPrice,
|
|
1244
1219
|
[Strategies.Identifiers.CollateralSwitch]: parseAaveV3CollateralSwitch,
|
|
1245
1220
|
[Strategies.Identifiers.LiquidationProtection]: parseAaveV3LiquidationProtection,
|
|
1246
1221
|
[Strategies.Identifiers.EoaLiquidationProtection]: parseAaveV3LiquidationProtection,
|
|
@@ -8,10 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { expect } from 'chai';
|
|
11
|
-
import {
|
|
11
|
+
import { ProtocolIdentifiers, Strategies } from '../types/enums';
|
|
12
12
|
import '../configuration';
|
|
13
13
|
import { parseStrategiesAutomatedPosition } from './strategiesService';
|
|
14
|
-
import { aaveV3Encode } from './strategySubService';
|
|
15
14
|
describe('Feature: strategiesService.ts', () => {
|
|
16
15
|
describe('When testing strategiesService.parseStrategiesAutomatedPosition', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
16
|
// TODO: we should probably write this for every strategy?
|
|
@@ -82,7 +81,6 @@ describe('Feature: strategiesService.ts', () => {
|
|
|
82
81
|
subId: '379',
|
|
83
82
|
proxy: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
|
|
84
83
|
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
85
|
-
// @ts-ignore
|
|
86
84
|
subStruct: {
|
|
87
85
|
strategyOrBundleId: '8',
|
|
88
86
|
isBundle: true,
|
|
@@ -107,65 +105,4 @@ describe('Feature: strategiesService.ts', () => {
|
|
|
107
105
|
}));
|
|
108
106
|
});
|
|
109
107
|
}));
|
|
110
|
-
describe('When parsing Aave V3 instant close bundles', () => {
|
|
111
|
-
const owner = '0x1234567890123456789012345678901234567890';
|
|
112
|
-
const market = '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e';
|
|
113
|
-
const weth = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
|
|
114
|
-
const usdc = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
|
|
115
|
-
const bundles = [
|
|
116
|
-
['SW', Bundles.MainnetIds.AAVE_V3_SW_INSTANT_CLOSE, Strategies.Identifiers.InstantCloseOnPrice],
|
|
117
|
-
['EOA', Bundles.MainnetIds.AAVE_V3_EOA_INSTANT_CLOSE, Strategies.Identifiers.EoaInstantCloseOnPrice],
|
|
118
|
-
];
|
|
119
|
-
bundles.forEach(([walletType, expectedBundleId, expectedStrategyId]) => {
|
|
120
|
-
describe(`${walletType} bundle`, () => {
|
|
121
|
-
const [bundleId, isBundle, triggerData, subData] = aaveV3Encode.instantCloseOnPriceGeneric(expectedBundleId, weth, 0, usdc, 1, market, owner, '1000000000000000000', '10000000000000000', 1500, CloseToAssetType.DEBT, 5000, CloseToAssetType.COLLATERAL);
|
|
122
|
-
const parseData = {
|
|
123
|
-
chainId: 1,
|
|
124
|
-
blockNumber: 1,
|
|
125
|
-
subscriptionEventData: {
|
|
126
|
-
subId: '1',
|
|
127
|
-
proxy: owner,
|
|
128
|
-
subHash: '0xhash',
|
|
129
|
-
subStruct: {
|
|
130
|
-
strategyOrBundleId: String(bundleId), isBundle, triggerData, subData,
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
strategiesSubsData: { userProxy: owner, isEnabled: true, strategySubHash: '0xhash' },
|
|
134
|
-
};
|
|
135
|
-
const result = parseStrategiesAutomatedPosition(parseData);
|
|
136
|
-
it('should identify the strategy as instant close on price', () => {
|
|
137
|
-
expect(result.strategy.strategyOrBundleId).to.equal(expectedBundleId);
|
|
138
|
-
expect(result.strategy.strategyId).to.equal(expectedStrategyId);
|
|
139
|
-
expect(result.protocol.id).to.equal(ProtocolIdentifiers.StrategiesAutomation.AaveV3);
|
|
140
|
-
});
|
|
141
|
-
it('should decode sub data including tsi and slippage', () => {
|
|
142
|
-
expect(result.strategyData.decoded.subData).to.eql({
|
|
143
|
-
collAsset: weth,
|
|
144
|
-
collAssetId: 0,
|
|
145
|
-
debtAsset: usdc,
|
|
146
|
-
debtAssetId: 1,
|
|
147
|
-
closeType: CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT,
|
|
148
|
-
marketAddr: market,
|
|
149
|
-
owner,
|
|
150
|
-
tsi: '1000000000000000000',
|
|
151
|
-
slippage: '10000000000000000',
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
it('should fill specific with prices and close types', () => {
|
|
155
|
-
expect(result.specific).to.eql({
|
|
156
|
-
collAsset: weth,
|
|
157
|
-
collAssetId: 0,
|
|
158
|
-
debtAsset: usdc,
|
|
159
|
-
debtAssetId: 1,
|
|
160
|
-
baseToken: weth,
|
|
161
|
-
quoteToken: usdc,
|
|
162
|
-
stopLossPrice: '1500',
|
|
163
|
-
takeProfitPrice: '5000',
|
|
164
|
-
stopLossType: CloseToAssetType.DEBT,
|
|
165
|
-
takeProfitType: CloseToAssetType.COLLATERAL,
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
108
|
});
|
|
@@ -61,7 +61,6 @@ export declare const aaveV3Encode: {
|
|
|
61
61
|
liquidationProtection(strategyOrBundleId: number, market: EthereumAddress, user: EthereumAddress, ratioState: RatioState, targetRatio: number, triggerRatio: number): (number | boolean | string[])[];
|
|
62
62
|
leverageManagementOnPriceGeneric(strategyOrBundleId: number, price: number, ratioState: RatioState, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, marketAddr: EthereumAddress, targetRatio: number, user: EthereumAddress): (number | boolean | string[])[];
|
|
63
63
|
closeOnPriceGeneric(strategyOrBundleId: number, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, marketAddr: EthereumAddress, user: EthereumAddress, stopLossPrice?: number, stopLossType?: CloseToAssetType, takeProfitPrice?: number, takeProfitType?: CloseToAssetType): (number | boolean | string[])[];
|
|
64
|
-
instantCloseOnPriceGeneric(strategyOrBundleId: number, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, marketAddr: EthereumAddress, user: EthereumAddress, tsi: string, slippage: string, stopLossPrice?: number, stopLossType?: CloseToAssetType, takeProfitPrice?: number, takeProfitType?: CloseToAssetType): (number | boolean | string[])[];
|
|
65
64
|
collateralSwitch(strategyOrBundleId: number, fromAsset: EthereumAddress, fromAssetId: number, toAsset: EthereumAddress, toAssetId: number, marketAddr: EthereumAddress, amountToSwitch: string, baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, state: RatioState): (number | boolean | string[])[];
|
|
66
65
|
};
|
|
67
66
|
export declare const compoundV2Encode: {
|
|
@@ -164,13 +164,6 @@ export const aaveV3Encode = {
|
|
|
164
164
|
const triggerDataEncoded = triggerService.aaveV3QuotePriceRangeTrigger.encode(collAsset, debtAsset, stopLossPrice, takeProfitPrice);
|
|
165
165
|
return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
|
|
166
166
|
},
|
|
167
|
-
instantCloseOnPriceGeneric(strategyOrBundleId, collAsset, collAssetId, debtAsset, debtAssetId, marketAddr, user, tsi, slippage, stopLossPrice = 0, stopLossType = CloseToAssetType.DEBT, takeProfitPrice = 0, takeProfitType = CloseToAssetType.COLLATERAL) {
|
|
168
|
-
const isBundle = true;
|
|
169
|
-
const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
|
|
170
|
-
const subDataEncoded = subDataService.aaveV3InstantCloseGenericSubData.encode(collAsset, collAssetId, debtAsset, debtAssetId, closeType, marketAddr, user, tsi, slippage);
|
|
171
|
-
const triggerDataEncoded = triggerService.aaveV3QuotePriceRangeTrigger.encode(collAsset, debtAsset, stopLossPrice, takeProfitPrice);
|
|
172
|
-
return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
|
|
173
|
-
},
|
|
174
167
|
collateralSwitch(strategyOrBundleId, fromAsset, fromAssetId, toAsset, toAssetId, marketAddr, amountToSwitch, baseTokenAddress, quoteTokenAddress, price, state) {
|
|
175
168
|
const isBundle = false;
|
|
176
169
|
const subDataEncoded = subDataService.aaveV3CollateralSwitchSubData.encode(fromAsset, fromAssetId, toAsset, toAssetId, marketAddr, amountToSwitch);
|