@strkfarm/sdk 2.0.0-dev.26 → 2.0.0-dev.28
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/dist/cli.js +190 -36
- package/dist/cli.mjs +188 -34
- package/dist/index.browser.global.js +79130 -49354
- package/dist/index.browser.mjs +18039 -11431
- package/dist/index.d.ts +2869 -898
- package/dist/index.js +19036 -12207
- package/dist/index.mjs +18942 -12158
- package/package.json +1 -1
- package/src/data/avnu.abi.json +840 -0
- package/src/data/ekubo-price-fethcer.abi.json +265 -0
- package/src/dataTypes/_bignumber.ts +13 -4
- package/src/dataTypes/index.ts +3 -2
- package/src/dataTypes/mynumber.ts +141 -0
- package/src/global.ts +76 -41
- package/src/index.browser.ts +2 -1
- package/src/interfaces/common.tsx +167 -2
- package/src/modules/ExtendedWrapperSDk/types.ts +26 -4
- package/src/modules/ExtendedWrapperSDk/wrapper.ts +110 -67
- package/src/modules/apollo-client-config.ts +28 -0
- package/src/modules/avnu.ts +4 -4
- package/src/modules/ekubo-pricer.ts +79 -0
- package/src/modules/ekubo-quoter.ts +46 -30
- package/src/modules/erc20.ts +17 -0
- package/src/modules/harvests.ts +43 -29
- package/src/modules/pragma.ts +23 -8
- package/src/modules/pricer-from-api.ts +156 -15
- package/src/modules/pricer-lst.ts +1 -1
- package/src/modules/pricer.ts +40 -4
- package/src/modules/pricerBase.ts +2 -1
- package/src/node/deployer.ts +36 -1
- package/src/node/pricer-redis.ts +2 -1
- package/src/strategies/base-strategy.ts +78 -10
- package/src/strategies/ekubo-cl-vault.tsx +906 -347
- package/src/strategies/factory.ts +159 -0
- package/src/strategies/index.ts +6 -1
- package/src/strategies/registry.ts +239 -0
- package/src/strategies/sensei.ts +335 -7
- package/src/strategies/svk-strategy.ts +97 -27
- package/src/strategies/types.ts +4 -0
- package/src/strategies/universal-adapters/adapter-utils.ts +2 -1
- package/src/strategies/universal-adapters/avnu-adapter.ts +177 -268
- package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
- package/src/strategies/universal-adapters/common-adapter.ts +206 -203
- package/src/strategies/universal-adapters/extended-adapter.ts +155 -336
- package/src/strategies/universal-adapters/index.ts +9 -8
- package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
- package/src/strategies/universal-adapters/usdc<>usdce-adapter.ts +200 -0
- package/src/strategies/universal-adapters/vesu-adapter.ts +110 -75
- package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +476 -0
- package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +762 -844
- package/src/strategies/universal-adapters/vesu-position-common.ts +251 -0
- package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
- package/src/strategies/universal-lst-muliplier-strategy.tsx +396 -204
- package/src/strategies/universal-strategy.tsx +1426 -1178
- package/src/strategies/vesu-extended-strategy/services/executionService.ts +2251 -0
- package/src/strategies/vesu-extended-strategy/services/extended-vesu-state-manager.ts +2941 -0
- package/src/strategies/vesu-extended-strategy/services/operationService.ts +12 -1
- package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +52 -0
- package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +1 -0
- package/src/strategies/vesu-extended-strategy/utils/constants.ts +3 -1
- package/src/strategies/vesu-extended-strategy/utils/helper.ts +158 -124
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +377 -1781
- package/src/strategies/vesu-rebalance.tsx +255 -152
- package/src/utils/health-factor-math.ts +4 -1
- package/src/utils/index.ts +2 -1
- package/src/utils/logger.browser.ts +22 -4
- package/src/utils/logger.node.ts +259 -24
- package/src/utils/starknet-call-parser.ts +1036 -0
- package/src/utils/strategy-utils.ts +61 -0
- package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { IConfig, IStrategyMetadata } from "@/interfaces";
|
|
2
|
+
import { PricerBase } from "@/modules/pricerBase";
|
|
3
|
+
import {
|
|
4
|
+
UniversalStrategy,
|
|
5
|
+
UniversalStrategySettings
|
|
6
|
+
} from "./universal-strategy";
|
|
7
|
+
import { EkuboCLVault, CLVaultStrategySettings } from "./ekubo-cl-vault";
|
|
8
|
+
import {
|
|
9
|
+
UniversalLstMultiplierStrategy,
|
|
10
|
+
HyperLSTStrategySettings
|
|
11
|
+
} from "./universal-lst-muliplier-strategy";
|
|
12
|
+
import { VesuRebalance, VesuRebalanceSettings } from "./vesu-rebalance";
|
|
13
|
+
import { SenseiVault, SenseiVaultSettings } from "./sensei";
|
|
14
|
+
|
|
15
|
+
export enum FactoryStrategyType {
|
|
16
|
+
UNIVERSAL = "UNIVERSAL",
|
|
17
|
+
EKUBO_CL = "EKUBO_CL",
|
|
18
|
+
HYPER_LST = "HYPER_LST",
|
|
19
|
+
VESU_REBALANCE = "VESU_REBALANCE",
|
|
20
|
+
SENSEI = "SENSEI"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createUniversalStrategy(
|
|
24
|
+
config: IConfig,
|
|
25
|
+
pricer: PricerBase,
|
|
26
|
+
metadata: IStrategyMetadata<UniversalStrategySettings>
|
|
27
|
+
): UniversalStrategy<UniversalStrategySettings> {
|
|
28
|
+
return new UniversalStrategy(config, pricer, metadata);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createEkuboCLStrategy(
|
|
32
|
+
config: IConfig,
|
|
33
|
+
pricer: PricerBase,
|
|
34
|
+
metadata: IStrategyMetadata<CLVaultStrategySettings>
|
|
35
|
+
): EkuboCLVault {
|
|
36
|
+
return new EkuboCLVault(config, pricer, metadata);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function createHyperLSTStrategy(
|
|
40
|
+
config: IConfig,
|
|
41
|
+
pricer: PricerBase,
|
|
42
|
+
metadata: IStrategyMetadata<HyperLSTStrategySettings>
|
|
43
|
+
): UniversalLstMultiplierStrategy<HyperLSTStrategySettings> {
|
|
44
|
+
return new UniversalLstMultiplierStrategy(config, pricer, metadata);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createVesuRebalanceStrategy(
|
|
48
|
+
config: IConfig,
|
|
49
|
+
pricer: PricerBase,
|
|
50
|
+
metadata: IStrategyMetadata<VesuRebalanceSettings>
|
|
51
|
+
): VesuRebalance {
|
|
52
|
+
return new VesuRebalance(config, pricer, metadata);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function createSenseiStrategy(
|
|
56
|
+
config: IConfig,
|
|
57
|
+
pricer: PricerBase,
|
|
58
|
+
metadata: IStrategyMetadata<SenseiVaultSettings>
|
|
59
|
+
): SenseiVault {
|
|
60
|
+
return new SenseiVault(config, pricer, metadata);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Determines the strategy type from metadata by inspecting the additionalInfo structure
|
|
65
|
+
*/
|
|
66
|
+
export function getStrategyTypeFromMetadata(
|
|
67
|
+
metadata: IStrategyMetadata<any>
|
|
68
|
+
): FactoryStrategyType {
|
|
69
|
+
const info = metadata.additionalInfo;
|
|
70
|
+
|
|
71
|
+
// Check for HyperLST (extends UniversalStrategySettings with borrowable_assets and underlyingToken)
|
|
72
|
+
if (info && "borrowable_assets" in info && "underlyingToken" in info) {
|
|
73
|
+
return FactoryStrategyType.HYPER_LST;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Check for EkuboCL (has newBounds, rebalanceConditions, quoteAsset)
|
|
77
|
+
if (
|
|
78
|
+
info &&
|
|
79
|
+
("newBounds" in info || typeof info.newBounds !== "undefined") &&
|
|
80
|
+
"rebalanceConditions" in info &&
|
|
81
|
+
"quoteAsset" in info
|
|
82
|
+
) {
|
|
83
|
+
return FactoryStrategyType.EKUBO_CL;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Check for Sensei (has mainToken, secondaryToken, targetHfBps)
|
|
87
|
+
if (
|
|
88
|
+
info &&
|
|
89
|
+
"mainToken" in info &&
|
|
90
|
+
"secondaryToken" in info &&
|
|
91
|
+
"targetHfBps" in info
|
|
92
|
+
) {
|
|
93
|
+
return FactoryStrategyType.SENSEI;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Check for VesuRebalance (has feeBps, but simpler structure)
|
|
97
|
+
if (info && "feeBps" in info && Object.keys(info).length <= 2) {
|
|
98
|
+
return FactoryStrategyType.VESU_REBALANCE;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Check for Universal (has vaultAddress, manager, vaultAllocator, etc.)
|
|
102
|
+
if (
|
|
103
|
+
info &&
|
|
104
|
+
"vaultAddress" in info &&
|
|
105
|
+
"manager" in info &&
|
|
106
|
+
"vaultAllocator" in info
|
|
107
|
+
) {
|
|
108
|
+
return FactoryStrategyType.UNIVERSAL;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Unable to determine strategy type from metadata: ${metadata.id}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Generic factory function that creates SDK strategy instances based on type
|
|
118
|
+
*/
|
|
119
|
+
export function createStrategy(
|
|
120
|
+
type: FactoryStrategyType,
|
|
121
|
+
config: IConfig,
|
|
122
|
+
pricer: PricerBase,
|
|
123
|
+
metadata: IStrategyMetadata<any>
|
|
124
|
+
) {
|
|
125
|
+
switch (type) {
|
|
126
|
+
case FactoryStrategyType.UNIVERSAL:
|
|
127
|
+
return createUniversalStrategy(
|
|
128
|
+
config,
|
|
129
|
+
pricer,
|
|
130
|
+
metadata as IStrategyMetadata<UniversalStrategySettings>
|
|
131
|
+
);
|
|
132
|
+
case FactoryStrategyType.EKUBO_CL:
|
|
133
|
+
return createEkuboCLStrategy(
|
|
134
|
+
config,
|
|
135
|
+
pricer,
|
|
136
|
+
metadata as IStrategyMetadata<CLVaultStrategySettings>
|
|
137
|
+
);
|
|
138
|
+
case FactoryStrategyType.HYPER_LST:
|
|
139
|
+
return createHyperLSTStrategy(
|
|
140
|
+
config,
|
|
141
|
+
pricer,
|
|
142
|
+
metadata as IStrategyMetadata<HyperLSTStrategySettings>
|
|
143
|
+
);
|
|
144
|
+
case FactoryStrategyType.VESU_REBALANCE:
|
|
145
|
+
return createVesuRebalanceStrategy(
|
|
146
|
+
config,
|
|
147
|
+
pricer,
|
|
148
|
+
metadata as IStrategyMetadata<VesuRebalanceSettings>
|
|
149
|
+
);
|
|
150
|
+
case FactoryStrategyType.SENSEI:
|
|
151
|
+
return createSenseiStrategy(
|
|
152
|
+
config,
|
|
153
|
+
pricer,
|
|
154
|
+
metadata as IStrategyMetadata<SenseiVaultSettings>
|
|
155
|
+
);
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(`Unknown strategy type: ${type}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
package/src/strategies/index.ts
CHANGED
|
@@ -9,4 +9,9 @@ export * from './universal-lst-muliplier-strategy';
|
|
|
9
9
|
export * from './vesu-extended-strategy/vesu-extended-strategy';
|
|
10
10
|
export * from './vesu-extended-strategy/utils/config.runtime';
|
|
11
11
|
export * from './vesu-extended-strategy/utils/helper';
|
|
12
|
-
export * from './vesu-extended-strategy/types/transaction-metadata';
|
|
12
|
+
export * from './vesu-extended-strategy/types/transaction-metadata';
|
|
13
|
+
export * from './vesu-extended-strategy/services/executionService';
|
|
14
|
+
export * from './vesu-extended-strategy/services/extended-vesu-state-manager';
|
|
15
|
+
export * from "./registry";
|
|
16
|
+
export * from "./factory";
|
|
17
|
+
export * from "./types";
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { getAllStrategyTags, IStrategyMetadata } from "@/interfaces";
|
|
2
|
+
import {
|
|
3
|
+
EkuboCLVaultStrategies,
|
|
4
|
+
CLVaultStrategySettings,
|
|
5
|
+
} from "./ekubo-cl-vault";
|
|
6
|
+
import {
|
|
7
|
+
HyperLSTStrategies,
|
|
8
|
+
HyperLSTStrategySettings,
|
|
9
|
+
} from "./universal-lst-muliplier-strategy";
|
|
10
|
+
import { UniversalStrategies } from "./universal-strategy";
|
|
11
|
+
import { VesuRebalanceStrategies } from "./vesu-rebalance";
|
|
12
|
+
import { SenseiStrategies } from "./sensei";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Filter option definition
|
|
16
|
+
*/
|
|
17
|
+
export interface FilterOption {
|
|
18
|
+
id: string;
|
|
19
|
+
label: string;
|
|
20
|
+
icon?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Strategy filter metadata - defines what filters are available
|
|
25
|
+
*/
|
|
26
|
+
export interface StrategyFilterMetadata {
|
|
27
|
+
assets: FilterOption[];
|
|
28
|
+
protocols: FilterOption[];
|
|
29
|
+
quickFilters: FilterOption[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Strategy type enum
|
|
34
|
+
*/
|
|
35
|
+
export enum StrategyType {
|
|
36
|
+
EKUBO_CL = "ekubo",
|
|
37
|
+
UNIVERSAL = "universal",
|
|
38
|
+
HYPER_LST = "hyper-lst",
|
|
39
|
+
VESU_REBALANCE = "vesu-rebalance",
|
|
40
|
+
SENSEI = "sensei",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Strategy metadata extracted from IStrategyMetadata
|
|
45
|
+
*/
|
|
46
|
+
export interface StrategyMetadata {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
type: StrategyType;
|
|
50
|
+
assets: string[]; // Token symbols (e.g., ["STRK", "USDC"])
|
|
51
|
+
protocols: string[]; // Protocol names (e.g., ["Ekubo"])
|
|
52
|
+
tags: string[];
|
|
53
|
+
curator?: { name: string; logo: string };
|
|
54
|
+
isRetired: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Strategy registry entry
|
|
59
|
+
*/
|
|
60
|
+
export interface StrategyRegistryEntry<T = any> {
|
|
61
|
+
metadata: IStrategyMetadata<T>;
|
|
62
|
+
type: StrategyType;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Extract assets from strategy metadata
|
|
67
|
+
*/
|
|
68
|
+
function extractAssets(metadata: IStrategyMetadata<any>): string[] {
|
|
69
|
+
const assets: string[] = [];
|
|
70
|
+
if (metadata.depositTokens) {
|
|
71
|
+
metadata.depositTokens.forEach((token) => {
|
|
72
|
+
const symbol = token.symbol?.toLowerCase() || "";
|
|
73
|
+
if (symbol) {
|
|
74
|
+
assets.push(symbol);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return assets;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Check if strategy is retired
|
|
83
|
+
*/
|
|
84
|
+
function isRetired(metadata: IStrategyMetadata<any>): boolean {
|
|
85
|
+
// Check liveStatus if available
|
|
86
|
+
const liveStatus = (metadata as any).liveStatus?.toLowerCase() || "";
|
|
87
|
+
return liveStatus === "retired" || liveStatus === "coming soon";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Build strategy registry from SDK strategies
|
|
92
|
+
*/
|
|
93
|
+
export function buildStrategyRegistry(): StrategyRegistryEntry[] {
|
|
94
|
+
const registry: StrategyRegistryEntry[] = [];
|
|
95
|
+
|
|
96
|
+
// Register Ekubo CL Vault strategies
|
|
97
|
+
if (EkuboCLVaultStrategies && Array.isArray(EkuboCLVaultStrategies)) {
|
|
98
|
+
EkuboCLVaultStrategies.forEach((metadata) => {
|
|
99
|
+
registry.push({
|
|
100
|
+
metadata,
|
|
101
|
+
type: StrategyType.EKUBO_CL,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Register Universal strategies
|
|
107
|
+
if (UniversalStrategies && Array.isArray(UniversalStrategies)) {
|
|
108
|
+
UniversalStrategies.forEach((metadata) => {
|
|
109
|
+
registry.push({
|
|
110
|
+
metadata,
|
|
111
|
+
type: StrategyType.UNIVERSAL,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Register Hyper LST strategies
|
|
117
|
+
if (HyperLSTStrategies && Array.isArray(HyperLSTStrategies)) {
|
|
118
|
+
HyperLSTStrategies.forEach((metadata) => {
|
|
119
|
+
registry.push({
|
|
120
|
+
metadata,
|
|
121
|
+
type: StrategyType.HYPER_LST,
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Register Vesu Rebalance strategies
|
|
127
|
+
if (VesuRebalanceStrategies && Array.isArray(VesuRebalanceStrategies)) {
|
|
128
|
+
VesuRebalanceStrategies.forEach((metadata) => {
|
|
129
|
+
registry.push({
|
|
130
|
+
metadata: metadata as any, // Type cast for compatibility
|
|
131
|
+
type: StrategyType.VESU_REBALANCE,
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Register Sensei strategies
|
|
137
|
+
if (SenseiStrategies && Array.isArray(SenseiStrategies)) {
|
|
138
|
+
SenseiStrategies.forEach((metadata) => {
|
|
139
|
+
registry.push({
|
|
140
|
+
metadata: metadata as any,
|
|
141
|
+
type: StrategyType.SENSEI,
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return registry;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get all strategy metadata from registry
|
|
151
|
+
*/
|
|
152
|
+
export function getAllStrategyMetadata(): StrategyMetadata[] {
|
|
153
|
+
const registry = buildStrategyRegistry();
|
|
154
|
+
return registry.map((entry) => {
|
|
155
|
+
const metadataAny = entry.metadata as any;
|
|
156
|
+
return {
|
|
157
|
+
id: metadataAny.id || entry.metadata.name || "unknown",
|
|
158
|
+
name: entry.metadata.name || "Unknown Strategy",
|
|
159
|
+
type: entry.type,
|
|
160
|
+
assets: extractAssets(entry.metadata),
|
|
161
|
+
protocols: entry.metadata.protocols.map(p => p.name.toLowerCase()),
|
|
162
|
+
tags: entry.metadata.tags || [],
|
|
163
|
+
curator: entry.metadata.curator,
|
|
164
|
+
isRetired: isRetired(entry.metadata),
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get filter metadata - defines available filters and their options
|
|
171
|
+
*/
|
|
172
|
+
export function getFilterMetadata(): StrategyFilterMetadata {
|
|
173
|
+
const allMetadata = getAllStrategyMetadata();
|
|
174
|
+
|
|
175
|
+
// Extract unique assets
|
|
176
|
+
const assetSet = new Set<string>();
|
|
177
|
+
allMetadata.forEach((meta) => {
|
|
178
|
+
meta.assets.forEach((asset) => assetSet.add(asset));
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const allowedAssets = new Set(["eth", "btc", "strk", "usdt", "usdc"]);
|
|
182
|
+
const assets: FilterOption[] = Array.from(assetSet)
|
|
183
|
+
.filter((asset) => allowedAssets.has(asset.toLowerCase()))
|
|
184
|
+
.sort((a, b) => {
|
|
185
|
+
// Sort in specific order: ETH, BTC, STRK, USDT, USDC
|
|
186
|
+
const order = ["eth", "btc", "strk", "usdt", "usdc"];
|
|
187
|
+
const aIndex = order.indexOf(a.toLowerCase());
|
|
188
|
+
const bIndex = order.indexOf(b.toLowerCase());
|
|
189
|
+
if (aIndex === -1 && bIndex === -1) return 0;
|
|
190
|
+
if (aIndex === -1) return 1;
|
|
191
|
+
if (bIndex === -1) return -1;
|
|
192
|
+
return aIndex - bIndex;
|
|
193
|
+
})
|
|
194
|
+
.map((id) => ({
|
|
195
|
+
id,
|
|
196
|
+
label: id.toUpperCase()
|
|
197
|
+
}));
|
|
198
|
+
|
|
199
|
+
// Extract unique protocols
|
|
200
|
+
const protocolSet = new Set<string>();
|
|
201
|
+
allMetadata.forEach((meta) => {
|
|
202
|
+
meta.protocols.forEach((protocol) => protocolSet.add(protocol));
|
|
203
|
+
});
|
|
204
|
+
const protocols: FilterOption[] = Array.from(protocolSet)
|
|
205
|
+
.sort()
|
|
206
|
+
.map((id) => ({
|
|
207
|
+
id,
|
|
208
|
+
label: id.charAt(0).toUpperCase() + id.slice(1)
|
|
209
|
+
}));
|
|
210
|
+
|
|
211
|
+
const quickFilters: FilterOption[] = [
|
|
212
|
+
{ id: "all", label: "All Strategies" },
|
|
213
|
+
...getAllStrategyTags().map((tag) => ({ id: tag.toLowerCase().replaceAll(" ", "-"), label: tag })),
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
assets,
|
|
218
|
+
protocols,
|
|
219
|
+
quickFilters
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get live strategies (filter out retired)
|
|
225
|
+
*/
|
|
226
|
+
export function getLiveStrategies(): StrategyRegistryEntry[] {
|
|
227
|
+
const registry = buildStrategyRegistry();
|
|
228
|
+
return registry.filter((entry) => !isRetired(entry.metadata));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Get strategies by type
|
|
233
|
+
*/
|
|
234
|
+
export function getStrategiesByType(
|
|
235
|
+
type: StrategyType,
|
|
236
|
+
): StrategyRegistryEntry[] {
|
|
237
|
+
const registry = buildStrategyRegistry();
|
|
238
|
+
return registry.filter((entry) => entry.type === type);
|
|
239
|
+
}
|