@defisaver/automation-sdk 3.3.18-spark-eoa-v2-dev → 3.3.19-sub-fetching-dev
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 +19 -2
- package/cjs/automation/private/StrategiesAutomation.test.js +55 -0
- 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 +69 -0
- package/cjs/services/strategiesService.test.js +0 -1
- package/cjs/types/enums.d.ts +6 -0
- package/cjs/types/enums.js +8 -1
- package/cjs/types/index.d.ts +29 -3
- package/esm/automation/private/StrategiesAutomation.d.ts +5 -1
- package/esm/automation/private/StrategiesAutomation.js +20 -3
- package/esm/automation/private/StrategiesAutomation.test.js +56 -1
- 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 +67 -0
- package/esm/services/strategiesService.test.js +0 -1
- package/esm/types/enums.d.ts +6 -0
- package/esm/types/enums.js +7 -0
- package/esm/types/index.d.ts +29 -3
- package/package.json +1 -1
- package/src/automation/private/StrategiesAutomation.test.ts +70 -1
- package/src/automation/private/StrategiesAutomation.ts +25 -1
- package/src/services/apiSubscriptionsService.test.ts +75 -0
- package/src/services/apiSubscriptionsService.ts +33 -0
- package/src/services/strategiesService.test.ts +0 -1
- package/src/types/enums.ts +7 -0
- package/src/types/index.ts +31 -2
|
@@ -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 {};
|
|
@@ -19,6 +19,7 @@ const utils_1 = require("../../services/utils");
|
|
|
19
19
|
const contractService_1 = require("../../services/contractService");
|
|
20
20
|
const ethereumService_1 = require("../../services/ethereumService");
|
|
21
21
|
const strategiesService_1 = require("../../services/strategiesService");
|
|
22
|
+
const apiSubscriptionsService_1 = require("../../services/apiSubscriptionsService");
|
|
22
23
|
const Automation_1 = __importDefault(require("./Automation"));
|
|
23
24
|
class StrategiesAutomation extends Automation_1.default {
|
|
24
25
|
constructor(args) {
|
|
@@ -126,9 +127,11 @@ class StrategiesAutomation extends Automation_1.default {
|
|
|
126
127
|
if (mergePairIndex !== -1) {
|
|
127
128
|
const mergePair = mergeExtension[mergePairIndex];
|
|
128
129
|
mergeExtension.splice(mergePairIndex, 1);
|
|
129
|
-
subscriptions.push(Object.assign(Object.assign(Object.assign({}, mergePair), current), {
|
|
130
|
+
subscriptions.push(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, mergePair), current), {
|
|
130
131
|
// @ts-ignore
|
|
131
|
-
blockNumber: decimal_js_1.default.max(mergePair.blockNumber, current.blockNumber).toNumber(), subIds: [current.subId, mergePair.subId], isEnabled: mergePair.isEnabled || current.isEnabled,
|
|
132
|
+
blockNumber: decimal_js_1.default.max(mergePair.blockNumber, current.blockNumber).toNumber(), subIds: [current.subId, mergePair.subId], isEnabled: mergePair.isEnabled || current.isEnabled }), (0, utils_1.addToObjectIf)((0, utils_1.isDefined)(current.status), {
|
|
133
|
+
status: mergePair.status === enums_1.SubscriptionStatus.Active ? enums_1.SubscriptionStatus.Active : current.status,
|
|
134
|
+
})), { specific: Object.assign(Object.assign({}, mergePair.specific), current.specific) }));
|
|
132
135
|
}
|
|
133
136
|
else {
|
|
134
137
|
subscriptions.push(Object.assign(Object.assign({}, current), { subIds: [current.subId] }));
|
|
@@ -189,6 +192,20 @@ class StrategiesAutomation extends Automation_1.default {
|
|
|
189
192
|
return this._getSubscriptions(undefined, options);
|
|
190
193
|
});
|
|
191
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* @description Parses subscriptions returned by the automation API (GET /v1/subscriptions)
|
|
197
|
+
*/
|
|
198
|
+
parseSubscriptionsFromApi(records, options) {
|
|
199
|
+
const filtered = (options === null || options === void 0 ? void 0 : options.enabledOnly) ? records.filter((record) => record.is_enabled) : records;
|
|
200
|
+
let subscriptions = filtered.map((record) => {
|
|
201
|
+
const position = this.getParsedSubscriptions((0, apiSubscriptionsService_1.parseDataFromApiSubscription)(record, this.chainId));
|
|
202
|
+
return position && Object.assign(Object.assign({}, position), { status: record.status });
|
|
203
|
+
});
|
|
204
|
+
if (options === null || options === void 0 ? void 0 : options.mergeSubs) {
|
|
205
|
+
subscriptions = this.mergeSubs(subscriptions);
|
|
206
|
+
}
|
|
207
|
+
return (options === null || options === void 0 ? void 0 : options.unexpiredOnly) ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
|
|
208
|
+
}
|
|
192
209
|
getSubscriptionsFor(addresses, options) {
|
|
193
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
194
211
|
return this._getSubscriptions(addresses, options);
|
|
@@ -693,4 +693,59 @@ describe('Feature: StrategiesAutomation.ts', () => {
|
|
|
693
693
|
(0, chai_1.expect)(loneBoost === null || loneBoost === void 0 ? void 0 : loneBoost.subId).to.equal(1);
|
|
694
694
|
});
|
|
695
695
|
}));
|
|
696
|
+
describe('When testing StrategiesAutomation.parseSubscriptionsFromApi', () => {
|
|
697
|
+
const strategiesAutomation = new StrategiesAutomation_1.default({
|
|
698
|
+
chainId: enums_1.ChainId.Ethereum,
|
|
699
|
+
provider: Web3_1,
|
|
700
|
+
providerFork: null,
|
|
701
|
+
});
|
|
702
|
+
const owner = '0x9cB7E19861665366011899d74E75d4F2A419aEeD';
|
|
703
|
+
const subData = [
|
|
704
|
+
'0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
|
|
705
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
706
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
707
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
708
|
+
];
|
|
709
|
+
// Aave V3 leverage management: repay (bundle 8, ratio under) and boost (bundle 9, ratio over) for the same owner and market
|
|
710
|
+
const repay = {
|
|
711
|
+
id: 379,
|
|
712
|
+
wallet: owner,
|
|
713
|
+
wallet_type: 'safe',
|
|
714
|
+
is_enabled: true,
|
|
715
|
+
invalid: false,
|
|
716
|
+
status: enums_1.SubscriptionStatus.Active,
|
|
717
|
+
is_bundle: true,
|
|
718
|
+
strategy_or_bundle_id: 8,
|
|
719
|
+
strategy_ids: [34, 35],
|
|
720
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
721
|
+
trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001'],
|
|
722
|
+
sub_data: subData,
|
|
723
|
+
block_number: 18015756,
|
|
724
|
+
additional_triggers: null,
|
|
725
|
+
};
|
|
726
|
+
const boost = Object.assign(Object.assign({}, repay), { id: 380, is_enabled: false, status: enums_1.SubscriptionStatus.Disabled, strategy_or_bundle_id: 9, sub_data_hash: '0x1111111111111111111111111111111111111111111111111111111111111111', trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000000'] });
|
|
727
|
+
it('Given API records should return parsed positions carrying the API status', () => {
|
|
728
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost]);
|
|
729
|
+
(0, chai_1.expect)(positions).to.have.length(2);
|
|
730
|
+
(0, chai_1.expect)(positions.map((p) => p === null || p === void 0 ? void 0 : p.subId)).to.eql([379, 380]);
|
|
731
|
+
(0, chai_1.expect)(positions.map((p) => p === null || p === void 0 ? void 0 : p.status)).to.eql([enums_1.SubscriptionStatus.Active, enums_1.SubscriptionStatus.Disabled]);
|
|
732
|
+
(0, chai_1.expect)(positions.map((p) => p === null || p === void 0 ? void 0 : p.isEnabled)).to.eql([true, false]);
|
|
733
|
+
});
|
|
734
|
+
it('Given mergeSubs option should merge the repay and boost pair and keep the active status', () => {
|
|
735
|
+
var _a, _b, _c;
|
|
736
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { mergeSubs: true });
|
|
737
|
+
(0, chai_1.expect)(positions).to.have.length(1);
|
|
738
|
+
(0, chai_1.expect)((_a = positions[0]) === null || _a === void 0 ? void 0 : _a.subIds).to.eql([379, 380]);
|
|
739
|
+
(0, chai_1.expect)((_b = positions[0]) === null || _b === void 0 ? void 0 : _b.isEnabled).to.equal(true);
|
|
740
|
+
(0, chai_1.expect)((_c = positions[0]) === null || _c === void 0 ? void 0 : _c.status).to.equal(enums_1.SubscriptionStatus.Active);
|
|
741
|
+
});
|
|
742
|
+
it('Given enabledOnly option should drop disabled records before parsing', () => {
|
|
743
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { enabledOnly: true });
|
|
744
|
+
(0, chai_1.expect)(positions.map((p) => p === null || p === void 0 ? void 0 : p.subId)).to.eql([379]);
|
|
745
|
+
});
|
|
746
|
+
it('Given a record of an unknown strategy should return null for it', () => {
|
|
747
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([Object.assign(Object.assign({}, repay), { strategy_or_bundle_id: 9999 })]);
|
|
748
|
+
(0, chai_1.expect)(positions).to.eql([null]);
|
|
749
|
+
});
|
|
750
|
+
});
|
|
696
751
|
});
|
|
@@ -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,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseDataFromApiSubscription = void 0;
|
|
4
|
+
function addHexPrefix(value) {
|
|
5
|
+
return value.startsWith('0x') ? value : `0x${value}`;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* @description Maps a subscription record returned by the automation API to the data
|
|
9
|
+
* the parser expects from Subscribe events and SubStorage (trigger data is stored without 0x prefix)
|
|
10
|
+
*/
|
|
11
|
+
function parseDataFromApiSubscription(record, chainId) {
|
|
12
|
+
return {
|
|
13
|
+
chainId,
|
|
14
|
+
blockNumber: record.block_number,
|
|
15
|
+
subscriptionEventData: {
|
|
16
|
+
subId: record.id.toString(),
|
|
17
|
+
proxy: record.wallet,
|
|
18
|
+
subHash: record.sub_data_hash,
|
|
19
|
+
subStruct: {
|
|
20
|
+
strategyOrBundleId: record.strategy_or_bundle_id.toString(),
|
|
21
|
+
isBundle: record.is_bundle,
|
|
22
|
+
triggerData: record.trigger_data.map(addHexPrefix),
|
|
23
|
+
subData: record.sub_data.map(addHexPrefix),
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
strategiesSubsData: {
|
|
27
|
+
userProxy: record.wallet,
|
|
28
|
+
isEnabled: record.is_enabled,
|
|
29
|
+
strategySubHash: record.sub_data_hash,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
exports.parseDataFromApiSubscription = parseDataFromApiSubscription;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../configuration';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chai_1 = require("chai");
|
|
4
|
+
const enums_1 = require("../types/enums");
|
|
5
|
+
require("../configuration");
|
|
6
|
+
const apiSubscriptionsService_1 = require("./apiSubscriptionsService");
|
|
7
|
+
const strategiesService_1 = require("./strategiesService");
|
|
8
|
+
describe('Feature: apiSubscriptionsService.ts', () => {
|
|
9
|
+
describe('When testing apiSubscriptionsService.parseDataFromApiSubscription', () => {
|
|
10
|
+
// same subscription as in strategiesService.test.ts, in the shape the automation API returns it
|
|
11
|
+
const record = {
|
|
12
|
+
id: 379,
|
|
13
|
+
wallet: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
14
|
+
wallet_type: 'safe',
|
|
15
|
+
is_enabled: true,
|
|
16
|
+
invalid: false,
|
|
17
|
+
status: enums_1.SubscriptionStatus.Active,
|
|
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
|
+
const fromEvents = {
|
|
35
|
+
chainId: enums_1.ChainId.Ethereum,
|
|
36
|
+
blockNumber: 18015756,
|
|
37
|
+
subscriptionEventData: {
|
|
38
|
+
subId: '379',
|
|
39
|
+
proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
40
|
+
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
41
|
+
subStruct: {
|
|
42
|
+
strategyOrBundleId: '8',
|
|
43
|
+
isBundle: true,
|
|
44
|
+
triggerData: [
|
|
45
|
+
'0x0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
46
|
+
],
|
|
47
|
+
subData: record.sub_data,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
strategiesSubsData: {
|
|
51
|
+
userProxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
52
|
+
isEnabled: true,
|
|
53
|
+
strategySubHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
it('Given an API record should return the same parse data as Subscribe event and SubStorage would', () => {
|
|
57
|
+
(0, chai_1.expect)((0, apiSubscriptionsService_1.parseDataFromApiSubscription)(record, enums_1.ChainId.Ethereum)).to.eql(fromEvents);
|
|
58
|
+
});
|
|
59
|
+
it('Given an API record the parsed position should match the one parsed from events', () => {
|
|
60
|
+
const fromApi = (0, strategiesService_1.parseStrategiesAutomatedPosition)((0, apiSubscriptionsService_1.parseDataFromApiSubscription)(record, enums_1.ChainId.Ethereum));
|
|
61
|
+
(0, chai_1.expect)(fromApi).to.not.equal(null);
|
|
62
|
+
(0, chai_1.expect)(fromApi).to.eql((0, strategiesService_1.parseStrategiesAutomatedPosition)(fromEvents));
|
|
63
|
+
});
|
|
64
|
+
it('Given a disabled record should keep it disabled', () => {
|
|
65
|
+
const parseData = (0, apiSubscriptionsService_1.parseDataFromApiSubscription)(Object.assign(Object.assign({}, record), { is_enabled: false }), enums_1.ChainId.Ethereum);
|
|
66
|
+
(0, chai_1.expect)(parseData.strategiesSubsData.isEnabled).to.equal(false);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -83,7 +83,6 @@ describe('Feature: strategiesService.ts', () => {
|
|
|
83
83
|
subId: '379',
|
|
84
84
|
proxy: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
|
|
85
85
|
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
86
|
-
// @ts-ignore
|
|
87
86
|
subStruct: {
|
|
88
87
|
strategyOrBundleId: '8',
|
|
89
88
|
isBundle: true,
|
package/cjs/types/enums.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ export declare enum ChainId {
|
|
|
4
4
|
Arbitrum = 42161,
|
|
5
5
|
Base = 8453
|
|
6
6
|
}
|
|
7
|
+
export declare enum SubscriptionStatus {
|
|
8
|
+
Active = "active",
|
|
9
|
+
Disabled = "disabled",
|
|
10
|
+
Finished = "finished",
|
|
11
|
+
Invalid = "invalid"
|
|
12
|
+
}
|
|
7
13
|
export declare enum RatioState {
|
|
8
14
|
OVER = 0,
|
|
9
15
|
UNDER = 1
|
package/cjs/types/enums.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Bundles = exports.Strategies = exports.ProtocolIdentifiers = exports.CloseToAssetType = exports.CloseStrategyType = exports.DebtActionType = exports.CollActionType = exports.BundleProtocols = exports.OrderType = exports.RatioState = exports.ChainId = void 0;
|
|
3
|
+
exports.Bundles = exports.Strategies = exports.ProtocolIdentifiers = exports.CloseToAssetType = exports.CloseStrategyType = exports.DebtActionType = exports.CollActionType = exports.BundleProtocols = exports.OrderType = exports.RatioState = exports.SubscriptionStatus = exports.ChainId = void 0;
|
|
4
4
|
var ChainId;
|
|
5
5
|
(function (ChainId) {
|
|
6
6
|
ChainId[ChainId["Ethereum"] = 1] = "Ethereum";
|
|
@@ -8,6 +8,13 @@ var ChainId;
|
|
|
8
8
|
ChainId[ChainId["Arbitrum"] = 42161] = "Arbitrum";
|
|
9
9
|
ChainId[ChainId["Base"] = 8453] = "Base";
|
|
10
10
|
})(ChainId = exports.ChainId || (exports.ChainId = {}));
|
|
11
|
+
var SubscriptionStatus;
|
|
12
|
+
(function (SubscriptionStatus) {
|
|
13
|
+
SubscriptionStatus["Active"] = "active";
|
|
14
|
+
SubscriptionStatus["Disabled"] = "disabled";
|
|
15
|
+
SubscriptionStatus["Finished"] = "finished";
|
|
16
|
+
SubscriptionStatus["Invalid"] = "invalid";
|
|
17
|
+
})(SubscriptionStatus = exports.SubscriptionStatus || (exports.SubscriptionStatus = {}));
|
|
11
18
|
var RatioState;
|
|
12
19
|
(function (RatioState) {
|
|
13
20
|
RatioState[RatioState["OVER"] = 0] = "OVER";
|
package/cjs/types/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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 {
|
|
5
|
-
import type { ChainId, Strategies, Bundles, ProtocolIdentifiers, RatioState, CloseToAssetType } from './enums';
|
|
4
|
+
import type { StrategyModel } from './contracts/generated/SubStorage';
|
|
5
|
+
import type { ChainId, Strategies, Bundles, ProtocolIdentifiers, RatioState, CloseToAssetType, SubscriptionStatus } from './enums';
|
|
6
6
|
export type PlaceholderType = any;
|
|
7
7
|
export type EthereumAddress = string;
|
|
8
8
|
export type BlockNumber = BlockType;
|
|
@@ -53,6 +53,23 @@ 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
|
+
invalid: boolean;
|
|
63
|
+
status: SubscriptionStatus;
|
|
64
|
+
is_bundle: boolean;
|
|
65
|
+
strategy_or_bundle_id: number;
|
|
66
|
+
strategy_ids: number[];
|
|
67
|
+
sub_data_hash: string;
|
|
68
|
+
trigger_data: string[];
|
|
69
|
+
sub_data: string[];
|
|
70
|
+
block_number: number;
|
|
71
|
+
additional_triggers: string[] | null;
|
|
72
|
+
}
|
|
56
73
|
export declare namespace Interfaces {
|
|
57
74
|
interface ProtocolBase {
|
|
58
75
|
id: ProtocolIdentifiers.StrategiesAutomation | ProtocolIdentifiers.LegacyAutomation;
|
|
@@ -238,6 +255,8 @@ export declare namespace Position {
|
|
|
238
255
|
subId: number;
|
|
239
256
|
subIds?: number[];
|
|
240
257
|
isEnabled?: boolean;
|
|
258
|
+
/** Set only for subscriptions parsed from the automation API */
|
|
259
|
+
status?: SubscriptionStatus;
|
|
241
260
|
subHash: string;
|
|
242
261
|
blockNumber: BlockNumber;
|
|
243
262
|
protocol: Interfaces.Protocol;
|
|
@@ -291,10 +310,17 @@ export interface BundlesInfo {
|
|
|
291
310
|
[ChainId.Base]: BaseBundleInfo;
|
|
292
311
|
}
|
|
293
312
|
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];
|
|
313
|
+
/** Fields of the Subscribe event that parsing relies on */
|
|
314
|
+
export interface SubscriptionEventData {
|
|
315
|
+
subId: string;
|
|
316
|
+
proxy: EthereumAddress;
|
|
317
|
+
subHash: string;
|
|
318
|
+
subStruct: StrategyModel.StrategySubStructOutputStruct;
|
|
319
|
+
}
|
|
294
320
|
export interface ParseData {
|
|
295
321
|
chainId: ChainId;
|
|
296
322
|
blockNumber: BlockNumber;
|
|
297
|
-
subscriptionEventData:
|
|
323
|
+
subscriptionEventData: SubscriptionEventData;
|
|
298
324
|
strategiesSubsData: StrategyModel.StoredSubDataStructOutputStruct;
|
|
299
325
|
}
|
|
300
326
|
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 {};
|
|
@@ -9,11 +9,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import Dec from 'decimal.js';
|
|
11
11
|
import PromisePool from 'es6-promise-pool';
|
|
12
|
-
import { Strategies, ProtocolIdentifiers } from '../../types/enums';
|
|
12
|
+
import { Strategies, ProtocolIdentifiers, SubscriptionStatus } from '../../types/enums';
|
|
13
13
|
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) {
|
|
@@ -121,9 +122,11 @@ export default class StrategiesAutomation extends Automation {
|
|
|
121
122
|
if (mergePairIndex !== -1) {
|
|
122
123
|
const mergePair = mergeExtension[mergePairIndex];
|
|
123
124
|
mergeExtension.splice(mergePairIndex, 1);
|
|
124
|
-
subscriptions.push(Object.assign(Object.assign(Object.assign({}, mergePair), current), {
|
|
125
|
+
subscriptions.push(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, mergePair), current), {
|
|
125
126
|
// @ts-ignore
|
|
126
|
-
blockNumber: Dec.max(mergePair.blockNumber, current.blockNumber).toNumber(), subIds: [current.subId, mergePair.subId], isEnabled: mergePair.isEnabled || current.isEnabled
|
|
127
|
+
blockNumber: Dec.max(mergePair.blockNumber, current.blockNumber).toNumber(), subIds: [current.subId, mergePair.subId], isEnabled: mergePair.isEnabled || current.isEnabled }), addToObjectIf(isDefined(current.status), {
|
|
128
|
+
status: mergePair.status === SubscriptionStatus.Active ? SubscriptionStatus.Active : current.status,
|
|
129
|
+
})), { specific: Object.assign(Object.assign({}, mergePair.specific), current.specific) }));
|
|
127
130
|
}
|
|
128
131
|
else {
|
|
129
132
|
subscriptions.push(Object.assign(Object.assign({}, current), { subIds: [current.subId] }));
|
|
@@ -184,6 +187,20 @@ export default class StrategiesAutomation extends Automation {
|
|
|
184
187
|
return this._getSubscriptions(undefined, options);
|
|
185
188
|
});
|
|
186
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* @description Parses subscriptions returned by the automation API (GET /v1/subscriptions)
|
|
192
|
+
*/
|
|
193
|
+
parseSubscriptionsFromApi(records, options) {
|
|
194
|
+
const filtered = (options === null || options === void 0 ? void 0 : options.enabledOnly) ? records.filter((record) => record.is_enabled) : records;
|
|
195
|
+
let subscriptions = filtered.map((record) => {
|
|
196
|
+
const position = this.getParsedSubscriptions(parseDataFromApiSubscription(record, this.chainId));
|
|
197
|
+
return position && Object.assign(Object.assign({}, position), { status: record.status });
|
|
198
|
+
});
|
|
199
|
+
if (options === null || options === void 0 ? void 0 : options.mergeSubs) {
|
|
200
|
+
subscriptions = this.mergeSubs(subscriptions);
|
|
201
|
+
}
|
|
202
|
+
return (options === null || options === void 0 ? void 0 : options.unexpiredOnly) ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
|
|
203
|
+
}
|
|
187
204
|
getSubscriptionsFor(addresses, options) {
|
|
188
205
|
return __awaiter(this, void 0, void 0, function* () {
|
|
189
206
|
return this._getSubscriptions(addresses, options);
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import Web3 from 'web3';
|
|
11
11
|
import { expect } from 'chai';
|
|
12
|
-
import { ChainId } from '../../types/enums';
|
|
12
|
+
import { ChainId, SubscriptionStatus } from '../../types/enums';
|
|
13
13
|
import '../../configuration';
|
|
14
14
|
import StrategiesAutomation from './StrategiesAutomation';
|
|
15
15
|
require('dotenv').config({ path: '.env' });
|
|
@@ -688,4 +688,59 @@ 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
|
+
invalid: false,
|
|
711
|
+
status: SubscriptionStatus.Active,
|
|
712
|
+
is_bundle: true,
|
|
713
|
+
strategy_or_bundle_id: 8,
|
|
714
|
+
strategy_ids: [34, 35],
|
|
715
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
716
|
+
trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001'],
|
|
717
|
+
sub_data: subData,
|
|
718
|
+
block_number: 18015756,
|
|
719
|
+
additional_triggers: null,
|
|
720
|
+
};
|
|
721
|
+
const boost = Object.assign(Object.assign({}, repay), { id: 380, is_enabled: false, status: SubscriptionStatus.Disabled, strategy_or_bundle_id: 9, sub_data_hash: '0x1111111111111111111111111111111111111111111111111111111111111111', trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000000'] });
|
|
722
|
+
it('Given API records should return parsed positions carrying the API status', () => {
|
|
723
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost]);
|
|
724
|
+
expect(positions).to.have.length(2);
|
|
725
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.subId)).to.eql([379, 380]);
|
|
726
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.status)).to.eql([SubscriptionStatus.Active, SubscriptionStatus.Disabled]);
|
|
727
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.isEnabled)).to.eql([true, false]);
|
|
728
|
+
});
|
|
729
|
+
it('Given mergeSubs option should merge the repay and boost pair and keep the active status', () => {
|
|
730
|
+
var _a, _b, _c;
|
|
731
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { mergeSubs: true });
|
|
732
|
+
expect(positions).to.have.length(1);
|
|
733
|
+
expect((_a = positions[0]) === null || _a === void 0 ? void 0 : _a.subIds).to.eql([379, 380]);
|
|
734
|
+
expect((_b = positions[0]) === null || _b === void 0 ? void 0 : _b.isEnabled).to.equal(true);
|
|
735
|
+
expect((_c = positions[0]) === null || _c === void 0 ? void 0 : _c.status).to.equal(SubscriptionStatus.Active);
|
|
736
|
+
});
|
|
737
|
+
it('Given enabledOnly option should drop disabled records before parsing', () => {
|
|
738
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { enabledOnly: true });
|
|
739
|
+
expect(positions.map((p) => p === null || p === void 0 ? void 0 : p.subId)).to.eql([379]);
|
|
740
|
+
});
|
|
741
|
+
it('Given a record of an unknown strategy should return null for it', () => {
|
|
742
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([Object.assign(Object.assign({}, repay), { strategy_or_bundle_id: 9999 })]);
|
|
743
|
+
expect(positions).to.eql([null]);
|
|
744
|
+
});
|
|
745
|
+
});
|
|
691
746
|
});
|
|
@@ -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,67 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { ChainId, SubscriptionStatus } 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
|
+
invalid: false,
|
|
15
|
+
status: SubscriptionStatus.Active,
|
|
16
|
+
is_bundle: true,
|
|
17
|
+
strategy_or_bundle_id: 8,
|
|
18
|
+
strategy_ids: [34, 35],
|
|
19
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
20
|
+
trigger_data: [
|
|
21
|
+
'0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
22
|
+
],
|
|
23
|
+
sub_data: [
|
|
24
|
+
'0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
|
|
25
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
26
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
27
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
28
|
+
],
|
|
29
|
+
block_number: 18015756,
|
|
30
|
+
additional_triggers: null,
|
|
31
|
+
};
|
|
32
|
+
const fromEvents = {
|
|
33
|
+
chainId: ChainId.Ethereum,
|
|
34
|
+
blockNumber: 18015756,
|
|
35
|
+
subscriptionEventData: {
|
|
36
|
+
subId: '379',
|
|
37
|
+
proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
38
|
+
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
39
|
+
subStruct: {
|
|
40
|
+
strategyOrBundleId: '8',
|
|
41
|
+
isBundle: true,
|
|
42
|
+
triggerData: [
|
|
43
|
+
'0x0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
44
|
+
],
|
|
45
|
+
subData: record.sub_data,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
strategiesSubsData: {
|
|
49
|
+
userProxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
50
|
+
isEnabled: true,
|
|
51
|
+
strategySubHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
it('Given an API record should return the same parse data as Subscribe event and SubStorage would', () => {
|
|
55
|
+
expect(parseDataFromApiSubscription(record, ChainId.Ethereum)).to.eql(fromEvents);
|
|
56
|
+
});
|
|
57
|
+
it('Given an API record the parsed position should match the one parsed from events', () => {
|
|
58
|
+
const fromApi = parseStrategiesAutomatedPosition(parseDataFromApiSubscription(record, ChainId.Ethereum));
|
|
59
|
+
expect(fromApi).to.not.equal(null);
|
|
60
|
+
expect(fromApi).to.eql(parseStrategiesAutomatedPosition(fromEvents));
|
|
61
|
+
});
|
|
62
|
+
it('Given a disabled record should keep it disabled', () => {
|
|
63
|
+
const parseData = parseDataFromApiSubscription(Object.assign(Object.assign({}, record), { is_enabled: false }), ChainId.Ethereum);
|
|
64
|
+
expect(parseData.strategiesSubsData.isEnabled).to.equal(false);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -81,7 +81,6 @@ describe('Feature: strategiesService.ts', () => {
|
|
|
81
81
|
subId: '379',
|
|
82
82
|
proxy: '0x9cb7e19861665366011899d74e75d4f2a419aeed',
|
|
83
83
|
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
84
|
-
// @ts-ignore
|
|
85
84
|
subStruct: {
|
|
86
85
|
strategyOrBundleId: '8',
|
|
87
86
|
isBundle: true,
|
package/esm/types/enums.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ export declare enum ChainId {
|
|
|
4
4
|
Arbitrum = 42161,
|
|
5
5
|
Base = 8453
|
|
6
6
|
}
|
|
7
|
+
export declare enum SubscriptionStatus {
|
|
8
|
+
Active = "active",
|
|
9
|
+
Disabled = "disabled",
|
|
10
|
+
Finished = "finished",
|
|
11
|
+
Invalid = "invalid"
|
|
12
|
+
}
|
|
7
13
|
export declare enum RatioState {
|
|
8
14
|
OVER = 0,
|
|
9
15
|
UNDER = 1
|
package/esm/types/enums.js
CHANGED
|
@@ -5,6 +5,13 @@ export var ChainId;
|
|
|
5
5
|
ChainId[ChainId["Arbitrum"] = 42161] = "Arbitrum";
|
|
6
6
|
ChainId[ChainId["Base"] = 8453] = "Base";
|
|
7
7
|
})(ChainId || (ChainId = {}));
|
|
8
|
+
export var SubscriptionStatus;
|
|
9
|
+
(function (SubscriptionStatus) {
|
|
10
|
+
SubscriptionStatus["Active"] = "active";
|
|
11
|
+
SubscriptionStatus["Disabled"] = "disabled";
|
|
12
|
+
SubscriptionStatus["Finished"] = "finished";
|
|
13
|
+
SubscriptionStatus["Invalid"] = "invalid";
|
|
14
|
+
})(SubscriptionStatus || (SubscriptionStatus = {}));
|
|
8
15
|
export var RatioState;
|
|
9
16
|
(function (RatioState) {
|
|
10
17
|
RatioState[RatioState["OVER"] = 0] = "OVER";
|
package/esm/types/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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 {
|
|
5
|
-
import type { ChainId, Strategies, Bundles, ProtocolIdentifiers, RatioState, CloseToAssetType } from './enums';
|
|
4
|
+
import type { StrategyModel } from './contracts/generated/SubStorage';
|
|
5
|
+
import type { ChainId, Strategies, Bundles, ProtocolIdentifiers, RatioState, CloseToAssetType, SubscriptionStatus } from './enums';
|
|
6
6
|
export type PlaceholderType = any;
|
|
7
7
|
export type EthereumAddress = string;
|
|
8
8
|
export type BlockNumber = BlockType;
|
|
@@ -53,6 +53,23 @@ 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
|
+
invalid: boolean;
|
|
63
|
+
status: SubscriptionStatus;
|
|
64
|
+
is_bundle: boolean;
|
|
65
|
+
strategy_or_bundle_id: number;
|
|
66
|
+
strategy_ids: number[];
|
|
67
|
+
sub_data_hash: string;
|
|
68
|
+
trigger_data: string[];
|
|
69
|
+
sub_data: string[];
|
|
70
|
+
block_number: number;
|
|
71
|
+
additional_triggers: string[] | null;
|
|
72
|
+
}
|
|
56
73
|
export declare namespace Interfaces {
|
|
57
74
|
interface ProtocolBase {
|
|
58
75
|
id: ProtocolIdentifiers.StrategiesAutomation | ProtocolIdentifiers.LegacyAutomation;
|
|
@@ -238,6 +255,8 @@ export declare namespace Position {
|
|
|
238
255
|
subId: number;
|
|
239
256
|
subIds?: number[];
|
|
240
257
|
isEnabled?: boolean;
|
|
258
|
+
/** Set only for subscriptions parsed from the automation API */
|
|
259
|
+
status?: SubscriptionStatus;
|
|
241
260
|
subHash: string;
|
|
242
261
|
blockNumber: BlockNumber;
|
|
243
262
|
protocol: Interfaces.Protocol;
|
|
@@ -291,10 +310,17 @@ export interface BundlesInfo {
|
|
|
291
310
|
[ChainId.Base]: BaseBundleInfo;
|
|
292
311
|
}
|
|
293
312
|
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];
|
|
313
|
+
/** Fields of the Subscribe event that parsing relies on */
|
|
314
|
+
export interface SubscriptionEventData {
|
|
315
|
+
subId: string;
|
|
316
|
+
proxy: EthereumAddress;
|
|
317
|
+
subHash: string;
|
|
318
|
+
subStruct: StrategyModel.StrategySubStructOutputStruct;
|
|
319
|
+
}
|
|
294
320
|
export interface ParseData {
|
|
295
321
|
chainId: ChainId;
|
|
296
322
|
blockNumber: BlockNumber;
|
|
297
|
-
subscriptionEventData:
|
|
323
|
+
subscriptionEventData: SubscriptionEventData;
|
|
298
324
|
strategiesSubsData: StrategyModel.StoredSubDataStructOutputStruct;
|
|
299
325
|
}
|
|
300
326
|
type MapToProtocolVersion<T> = {
|
package/package.json
CHANGED
|
@@ -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, SubscriptionStatus } from '../../types/enums';
|
|
5
|
+
import type { ApiSubscriptionRecord } from '../../types';
|
|
5
6
|
|
|
6
7
|
import '../../configuration';
|
|
7
8
|
import StrategiesAutomation from './StrategiesAutomation';
|
|
@@ -700,4 +701,72 @@ 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
|
+
invalid: false,
|
|
726
|
+
status: SubscriptionStatus.Active,
|
|
727
|
+
is_bundle: true,
|
|
728
|
+
strategy_or_bundle_id: 8,
|
|
729
|
+
strategy_ids: [34, 35],
|
|
730
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
731
|
+
trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001'],
|
|
732
|
+
sub_data: subData,
|
|
733
|
+
block_number: 18015756,
|
|
734
|
+
additional_triggers: null,
|
|
735
|
+
};
|
|
736
|
+
const boost: ApiSubscriptionRecord = {
|
|
737
|
+
...repay,
|
|
738
|
+
id: 380,
|
|
739
|
+
is_enabled: false,
|
|
740
|
+
status: SubscriptionStatus.Disabled,
|
|
741
|
+
strategy_or_bundle_id: 9,
|
|
742
|
+
sub_data_hash: '0x1111111111111111111111111111111111111111111111111111111111111111',
|
|
743
|
+
trigger_data: ['0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000000'],
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
it('Given API records should return parsed positions carrying the API status', () => {
|
|
747
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost]);
|
|
748
|
+
expect(positions).to.have.length(2);
|
|
749
|
+
expect(positions.map((p) => p?.subId)).to.eql([379, 380]);
|
|
750
|
+
expect(positions.map((p) => p?.status)).to.eql([SubscriptionStatus.Active, SubscriptionStatus.Disabled]);
|
|
751
|
+
expect(positions.map((p) => p?.isEnabled)).to.eql([true, false]);
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
it('Given mergeSubs option should merge the repay and boost pair and keep the active status', () => {
|
|
755
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { mergeSubs: true });
|
|
756
|
+
expect(positions).to.have.length(1);
|
|
757
|
+
expect(positions[0]?.subIds).to.eql([379, 380]);
|
|
758
|
+
expect(positions[0]?.isEnabled).to.equal(true);
|
|
759
|
+
expect(positions[0]?.status).to.equal(SubscriptionStatus.Active);
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
it('Given enabledOnly option should drop disabled records before parsing', () => {
|
|
763
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([repay, boost], { enabledOnly: true });
|
|
764
|
+
expect(positions.map((p) => p?.subId)).to.eql([379]);
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
it('Given a record of an unknown strategy should return null for it', () => {
|
|
768
|
+
const positions = strategiesAutomation.parseSubscriptionsFromApi([{ ...repay, strategy_or_bundle_id: 9999 }]);
|
|
769
|
+
expect(positions).to.eql([null]);
|
|
770
|
+
});
|
|
771
|
+
});
|
|
703
772
|
});
|
|
@@ -4,17 +4,19 @@ 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,
|
|
10
11
|
} from '../../types/contracts/generated/SubStorage';
|
|
11
12
|
import type { ChainId } from '../../types/enums';
|
|
12
|
-
import { Strategies, ProtocolIdentifiers } from '../../types/enums';
|
|
13
|
+
import { Strategies, ProtocolIdentifiers, SubscriptionStatus } from '../../types/enums';
|
|
13
14
|
|
|
14
15
|
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
|
|
|
@@ -167,6 +169,10 @@ export default class StrategiesAutomation extends Automation {
|
|
|
167
169
|
blockNumber: Dec.max(mergePair.blockNumber, current.blockNumber).toNumber(),
|
|
168
170
|
subIds: [current.subId, mergePair.subId],
|
|
169
171
|
isEnabled: mergePair.isEnabled || current.isEnabled,
|
|
172
|
+
// status is set only for subscriptions parsed from the automation API
|
|
173
|
+
...addToObjectIf(isDefined(current.status), {
|
|
174
|
+
status: mergePair.status === SubscriptionStatus.Active ? SubscriptionStatus.Active : current.status,
|
|
175
|
+
}),
|
|
170
176
|
specific: {
|
|
171
177
|
...mergePair.specific,
|
|
172
178
|
...current.specific,
|
|
@@ -259,6 +265,24 @@ export default class StrategiesAutomation extends Automation {
|
|
|
259
265
|
return this._getSubscriptions(undefined, options);
|
|
260
266
|
}
|
|
261
267
|
|
|
268
|
+
/**
|
|
269
|
+
* @description Parses subscriptions returned by the automation API (GET /v1/subscriptions)
|
|
270
|
+
*/
|
|
271
|
+
public parseSubscriptionsFromApi(records: ApiSubscriptionRecord[], options?: SubscriptionOptions): (Position.Automated | null)[] {
|
|
272
|
+
const filtered = options?.enabledOnly ? records.filter((record) => record.is_enabled) : records;
|
|
273
|
+
|
|
274
|
+
let subscriptions: (Position.Automated | null)[] = filtered.map((record) => {
|
|
275
|
+
const position = this.getParsedSubscriptions(parseDataFromApiSubscription(record, this.chainId));
|
|
276
|
+
return position && { ...position, status: record.status };
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
if (options?.mergeSubs) {
|
|
280
|
+
subscriptions = this.mergeSubs(subscriptions);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return options?.unexpiredOnly ? this.removeExpiredSubscriptions(subscriptions) : subscriptions;
|
|
284
|
+
}
|
|
285
|
+
|
|
262
286
|
public async getSubscriptionsFor(addresses: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]> {
|
|
263
287
|
return this._getSubscriptions(addresses, options);
|
|
264
288
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
|
|
3
|
+
import type { ApiSubscriptionRecord, ParseData } from '../types';
|
|
4
|
+
import { ChainId, SubscriptionStatus } 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
|
+
invalid: false,
|
|
19
|
+
status: SubscriptionStatus.Active,
|
|
20
|
+
is_bundle: true,
|
|
21
|
+
strategy_or_bundle_id: 8,
|
|
22
|
+
strategy_ids: [34, 35],
|
|
23
|
+
sub_data_hash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
24
|
+
trigger_data: [
|
|
25
|
+
'0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
26
|
+
],
|
|
27
|
+
sub_data: [
|
|
28
|
+
'0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
|
|
29
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
30
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
31
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
32
|
+
],
|
|
33
|
+
block_number: 18015756,
|
|
34
|
+
additional_triggers: null,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const fromEvents: ParseData = {
|
|
38
|
+
chainId: ChainId.Ethereum,
|
|
39
|
+
blockNumber: 18015756,
|
|
40
|
+
subscriptionEventData: {
|
|
41
|
+
subId: '379',
|
|
42
|
+
proxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
43
|
+
subHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
44
|
+
subStruct: {
|
|
45
|
+
strategyOrBundleId: '8',
|
|
46
|
+
isBundle: true,
|
|
47
|
+
triggerData: [
|
|
48
|
+
'0x0000000000000000000000009cb7e19861665366011899d74e75d4f2a419aeed0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000019ac8532c27900000000000000000000000000000000000000000000000000000000000000000001',
|
|
49
|
+
],
|
|
50
|
+
subData: record.sub_data,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
strategiesSubsData: {
|
|
54
|
+
userProxy: '0x9cB7E19861665366011899d74E75d4F2A419aEeD',
|
|
55
|
+
isEnabled: true,
|
|
56
|
+
strategySubHash: '0xafa4d200be62f171b57b1ae0f4e8348d1ac3f6d0812ad6da74a2adae8037dde1',
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
it('Given an API record should return the same parse data as Subscribe event and SubStorage would', () => {
|
|
61
|
+
expect(parseDataFromApiSubscription(record, ChainId.Ethereum)).to.eql(fromEvents);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('Given an API record the parsed position should match the one parsed from events', () => {
|
|
65
|
+
const fromApi = parseStrategiesAutomatedPosition(parseDataFromApiSubscription(record, ChainId.Ethereum));
|
|
66
|
+
expect(fromApi).to.not.equal(null);
|
|
67
|
+
expect(fromApi).to.eql(parseStrategiesAutomatedPosition(fromEvents));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('Given a disabled record should keep it disabled', () => {
|
|
71
|
+
const parseData = parseDataFromApiSubscription({ ...record, is_enabled: false }, ChainId.Ethereum);
|
|
72
|
+
expect(parseData.strategiesSubsData.isEnabled).to.equal(false);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -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',
|
package/src/types/enums.ts
CHANGED
package/src/types/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
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 {
|
|
6
6
|
ChainId, Strategies, Bundles, ProtocolIdentifiers,
|
|
7
7
|
RatioState,
|
|
8
8
|
CloseToAssetType,
|
|
9
|
+
SubscriptionStatus,
|
|
9
10
|
} from './enums';
|
|
10
11
|
|
|
11
12
|
export type PlaceholderType = any; // TODO - fix any types
|
|
@@ -72,6 +73,24 @@ interface _SubscriptionOptions {
|
|
|
72
73
|
|
|
73
74
|
export type SubscriptionOptions = Partial<_SubscriptionOptions>;
|
|
74
75
|
|
|
76
|
+
/** Subscription record as returned by the automation API (GET /v1/subscriptions) */
|
|
77
|
+
export interface ApiSubscriptionRecord {
|
|
78
|
+
id: number,
|
|
79
|
+
wallet: EthereumAddress,
|
|
80
|
+
wallet_type: string,
|
|
81
|
+
is_enabled: boolean,
|
|
82
|
+
invalid: boolean,
|
|
83
|
+
status: SubscriptionStatus,
|
|
84
|
+
is_bundle: boolean,
|
|
85
|
+
strategy_or_bundle_id: number,
|
|
86
|
+
strategy_ids: number[],
|
|
87
|
+
sub_data_hash: string,
|
|
88
|
+
trigger_data: string[],
|
|
89
|
+
sub_data: string[],
|
|
90
|
+
block_number: number,
|
|
91
|
+
additional_triggers: string[] | null,
|
|
92
|
+
}
|
|
93
|
+
|
|
75
94
|
export declare namespace Interfaces {
|
|
76
95
|
interface ProtocolBase {
|
|
77
96
|
id: ProtocolIdentifiers.StrategiesAutomation | ProtocolIdentifiers.LegacyAutomation,
|
|
@@ -301,6 +320,8 @@ export declare namespace Position {
|
|
|
301
320
|
subId: number,
|
|
302
321
|
subIds?: number[],
|
|
303
322
|
isEnabled?: boolean,
|
|
323
|
+
/** Set only for subscriptions parsed from the automation API */
|
|
324
|
+
status?: SubscriptionStatus,
|
|
304
325
|
subHash: string,
|
|
305
326
|
blockNumber: BlockNumber,
|
|
306
327
|
protocol: Interfaces.Protocol,
|
|
@@ -369,10 +390,18 @@ export type StrategyOrBundleIds =
|
|
|
369
390
|
| typeof Bundles.ArbitrumIds[keyof typeof Bundles.ArbitrumIds]
|
|
370
391
|
| typeof Bundles.BaseIds[keyof typeof Bundles.BaseIds];
|
|
371
392
|
|
|
393
|
+
/** Fields of the Subscribe event that parsing relies on */
|
|
394
|
+
export interface SubscriptionEventData {
|
|
395
|
+
subId: string,
|
|
396
|
+
proxy: EthereumAddress,
|
|
397
|
+
subHash: string,
|
|
398
|
+
subStruct: StrategyModel.StrategySubStructOutputStruct,
|
|
399
|
+
}
|
|
400
|
+
|
|
372
401
|
export interface ParseData {
|
|
373
402
|
chainId: ChainId,
|
|
374
403
|
blockNumber: BlockNumber,
|
|
375
|
-
subscriptionEventData:
|
|
404
|
+
subscriptionEventData: SubscriptionEventData,
|
|
376
405
|
strategiesSubsData: StrategyModel.StoredSubDataStructOutputStruct,
|
|
377
406
|
}
|
|
378
407
|
|