@strkfarm/sdk 1.0.15 → 1.0.17

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/index.d.ts CHANGED
@@ -1,28 +1,9 @@
1
- import { RpcProvider, BlockIdentifier, Contract, Account } from 'starknet';
2
1
  import BigNumber from 'bignumber.js';
2
+ import * as starknet from 'starknet';
3
+ import { RpcProvider, BlockIdentifier, Contract, Account } from 'starknet';
3
4
  import * as util from 'util';
4
5
  import TelegramBot from 'node-telegram-bot-api';
5
6
 
6
- interface TokenInfo {
7
- name: string;
8
- symbol: string;
9
- address: string;
10
- decimals: number;
11
- coingeckId?: string;
12
- }
13
- declare enum Network {
14
- mainnet = "mainnet",
15
- sepolia = "sepolia",
16
- devnet = "devnet"
17
- }
18
- interface IConfig {
19
- provider: RpcProvider;
20
- network: Network;
21
- stage: 'production' | 'staging';
22
- heartbeatUrl?: string;
23
- }
24
- declare function getMainnetConfig(rpcUrl?: string, blockIdentifier?: BlockIdentifier): IConfig;
25
-
26
7
  declare class Web3Number extends BigNumber {
27
8
  decimals: number;
28
9
  constructor(value: string | number, decimals: number);
@@ -49,43 +30,66 @@ declare class ContractAddr {
49
30
  static eqString(a: string, b: string): boolean;
50
31
  }
51
32
 
52
- interface PriceInfo {
53
- price: number;
54
- timestamp: Date;
33
+ declare enum RiskType {
34
+ MARKET_RISK = "MARKET_RISK",
35
+ IMPERMANENT_LOSS = "IMPERMANENT_LOSS",
36
+ LIQUIDITY_RISK = "LIQUIDITY_RISK",
37
+ SMART_CONTRACT_RISK = "SMART_CONTRACT_RISK",
38
+ TECHNICAL_RISK = "TECHNICAL_RISK",
39
+ COUNTERPARTY_RISK = "COUNTERPARTY_RISK"
55
40
  }
56
- declare class Pricer {
57
- readonly config: IConfig;
58
- readonly tokens: TokenInfo[];
59
- protected prices: {
60
- [key: string]: PriceInfo;
41
+ interface RiskFactor {
42
+ type: RiskType;
43
+ value: number;
44
+ weight: number;
45
+ }
46
+ interface TokenInfo {
47
+ name: string;
48
+ symbol: string;
49
+ address: string;
50
+ decimals: number;
51
+ logo: string;
52
+ coingeckId?: string;
53
+ }
54
+ declare enum Network {
55
+ mainnet = "mainnet",
56
+ sepolia = "sepolia",
57
+ devnet = "devnet"
58
+ }
59
+ interface IConfig {
60
+ provider: RpcProvider;
61
+ network: Network;
62
+ stage: 'production' | 'staging';
63
+ heartbeatUrl?: string;
64
+ }
65
+ interface IProtocol {
66
+ name: string;
67
+ logo: string;
68
+ }
69
+ /**
70
+ * @property risk.riskFactor.factor - The risk factors that are considered for the strategy.
71
+ * @property risk.riskFactor.factor - The value of the risk factor from 0 to 10, 0 being the lowest and 10 being the highest.
72
+ */
73
+ interface IStrategyMetadata {
74
+ name: string;
75
+ description: string;
76
+ address: ContractAddr;
77
+ type: 'ERC4626' | 'ERC721' | 'Other';
78
+ depositTokens: TokenInfo[];
79
+ protocols: IProtocol[];
80
+ auditUrl?: string;
81
+ maxTVL: Web3Number;
82
+ risk: {
83
+ riskFactor: RiskFactor[];
84
+ netRisk: number;
61
85
  };
62
- private methodToUse;
63
- /**
64
- * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
65
- */
66
- protected PRICE_API: string;
67
- protected EKUBO_API: string;
68
- protected client: any;
69
- constructor(config: IConfig, tokens: TokenInfo[]);
70
- isReady(): boolean;
71
- waitTillReady(): Promise<void>;
72
- start(): void;
73
- isStale(timestamp: Date, tokenName: string): boolean;
74
- assertNotStale(timestamp: Date, tokenName: string): void;
75
- getPrice(tokenName: string): Promise<PriceInfo>;
76
- protected _loadPrices(onUpdate?: (tokenSymbol: string) => void): void;
77
- _getPrice(token: TokenInfo, defaultMethod?: string): Promise<number>;
78
- _getPriceCoinbase(token: TokenInfo): Promise<number>;
79
- _getPriceCoinMarketCap(token: TokenInfo): Promise<number>;
80
- _getPriceEkubo(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
81
86
  }
82
-
83
- declare class Pragma {
84
- contractAddr: string;
85
- readonly contract: Contract;
86
- constructor(provider: RpcProvider);
87
- getPrice(tokenAddr: string): Promise<number>;
87
+ interface IInvestmentFlow {
88
+ title: string;
89
+ subItems: string[];
90
+ linkedFlows: IInvestmentFlow[];
88
91
  }
92
+ declare function getMainnetConfig(rpcUrl?: string, blockIdentifier?: BlockIdentifier): IConfig;
89
93
 
90
94
  interface ILendingMetadata {
91
95
  name: string;
@@ -139,6 +143,48 @@ declare abstract class Initializable {
139
143
  waitForInitilisation(): Promise<void>;
140
144
  }
141
145
 
146
+ declare abstract class PricerBase {
147
+ readonly config: IConfig;
148
+ readonly tokens: TokenInfo[];
149
+ constructor(config: IConfig, tokens: TokenInfo[]);
150
+ getPrice(tokenSymbol: string): Promise<PriceInfo>;
151
+ }
152
+
153
+ interface PriceInfo {
154
+ price: number;
155
+ timestamp: Date;
156
+ }
157
+ declare class Pricer extends PricerBase {
158
+ protected prices: {
159
+ [key: string]: PriceInfo;
160
+ };
161
+ private methodToUse;
162
+ /**
163
+ * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
164
+ */
165
+ protected PRICE_API: string;
166
+ protected EKUBO_API: string;
167
+ constructor(config: IConfig, tokens: TokenInfo[]);
168
+ isReady(): boolean;
169
+ waitTillReady(): Promise<void>;
170
+ start(): void;
171
+ isStale(timestamp: Date, tokenName: string): boolean;
172
+ assertNotStale(timestamp: Date, tokenName: string): void;
173
+ getPrice(tokenSymbol: string): Promise<PriceInfo>;
174
+ protected _loadPrices(onUpdate?: (tokenSymbol: string) => void): void;
175
+ _getPrice(token: TokenInfo, defaultMethod?: string): Promise<number>;
176
+ _getPriceCoinbase(token: TokenInfo): Promise<number>;
177
+ _getPriceCoinMarketCap(token: TokenInfo): Promise<number>;
178
+ _getPriceEkubo(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
179
+ }
180
+
181
+ declare class Pragma {
182
+ contractAddr: string;
183
+ readonly contract: Contract;
184
+ constructor(provider: RpcProvider);
185
+ getPrice(tokenAddr: string): Promise<number>;
186
+ }
187
+
142
188
  declare class ZkLend extends ILending implements ILending {
143
189
  readonly pricer: Pricer;
144
190
  static readonly POOLS_URL = "https://app.zklend.com/api/pools";
@@ -170,6 +216,15 @@ declare class ZkLend extends ILending implements ILending {
170
216
  getPositions(user: ContractAddr): Promise<ILendingPosition[]>;
171
217
  }
172
218
 
219
+ declare class PricerFromApi extends PricerBase {
220
+ constructor(config: IConfig, tokens: TokenInfo[]);
221
+ getPrice(tokenSymbol: string): Promise<PriceInfo>;
222
+ getPriceFromMyAPI(tokenSymbol: string): Promise<{
223
+ price: number;
224
+ timestamp: Date;
225
+ }>;
226
+ }
227
+
173
228
  declare const logger: {
174
229
  verbose(message: string): void;
175
230
  assert(condition?: boolean, ...data: any[]): void;
@@ -225,6 +280,7 @@ declare class FatalError extends Error {
225
280
  declare class Global {
226
281
  static fatalError(message: string, err?: Error): void;
227
282
  static httpError(url: string, err: Error, message?: string): void;
283
+ static getDefaultTokens(): TokenInfo[];
228
284
  static getTokens(): Promise<TokenInfo[]>;
229
285
  static assert(condition: any, message: string): void;
230
286
  }
@@ -258,6 +314,179 @@ declare class AutoCompounderSTRK {
258
314
  }>;
259
315
  }
260
316
 
317
+ interface Change {
318
+ pool_id: ContractAddr;
319
+ changeAmt: Web3Number;
320
+ finalAmt: Web3Number;
321
+ isDeposit: boolean;
322
+ }
323
+ interface PoolInfoFull {
324
+ pool_id: ContractAddr;
325
+ pool_name: string | undefined;
326
+ max_weight: number;
327
+ current_weight: number;
328
+ v_token: ContractAddr;
329
+ amount: Web3Number;
330
+ usdValue: Web3Number;
331
+ APY: {
332
+ baseApy: number;
333
+ defiSpringApy: number;
334
+ netApy: number;
335
+ };
336
+ currentUtilization: number;
337
+ maxUtilization: number;
338
+ }
339
+ /**
340
+ * Represents a VesuRebalance strategy.
341
+ * This class implements an automated rebalancing strategy for Vesu pools,
342
+ * managing deposits and withdrawals while optimizing yield through STRK rewards.
343
+ */
344
+ declare class VesuRebalance {
345
+ /** Configuration object for the strategy */
346
+ readonly config: IConfig;
347
+ /** Contract address of the strategy */
348
+ readonly address: ContractAddr;
349
+ /** Pricer instance for token price calculations */
350
+ readonly pricer: PricerBase;
351
+ /** Metadata containing strategy information */
352
+ readonly metadata: IStrategyMetadata;
353
+ /** Contract instance for interacting with the strategy */
354
+ readonly contract: Contract;
355
+ readonly BASE_WEIGHT = 10000;
356
+ /**
357
+ * Creates a new VesuRebalance strategy instance.
358
+ * @param config - Configuration object containing provider and other settings
359
+ * @param pricer - Pricer instance for token price calculations
360
+ * @param metadata - Strategy metadata including deposit tokens and address
361
+ * @throws {Error} If more than one deposit token is specified
362
+ */
363
+ constructor(config: IConfig, pricer: PricerBase, metadata: IStrategyMetadata);
364
+ /**
365
+ * Creates a deposit call to the strategy contract.
366
+ * @param assets - Amount of assets to deposit
367
+ * @param receiver - Address that will receive the strategy tokens
368
+ * @returns Populated contract call for deposit
369
+ */
370
+ depositCall(assets: Web3Number, receiver: ContractAddr): starknet.Call[];
371
+ /**
372
+ * Creates a withdrawal call to the strategy contract.
373
+ * @param assets - Amount of assets to withdraw
374
+ * @param receiver - Address that will receive the withdrawn assets
375
+ * @param owner - Address that owns the strategy tokens
376
+ * @returns Populated contract call for withdrawal
377
+ */
378
+ withdrawCall(assets: Web3Number, receiver: ContractAddr, owner: ContractAddr): starknet.Call[];
379
+ /**
380
+ * Returns the underlying asset token of the strategy.
381
+ * @returns The deposit token supported by this strategy
382
+ */
383
+ asset(): TokenInfo;
384
+ /**
385
+ * Returns the number of decimals used by the strategy token.
386
+ * @returns Number of decimals (same as the underlying token)
387
+ */
388
+ decimals(): number;
389
+ /**
390
+ * Calculates the Total Value Locked (TVL) for a specific user.
391
+ * @param user - Address of the user
392
+ * @returns Object containing the amount in token units and USD value
393
+ */
394
+ getUserTVL(user: ContractAddr): Promise<{
395
+ amount: Web3Number;
396
+ usdValue: number;
397
+ }>;
398
+ /**
399
+ * Calculates the total TVL of the strategy.
400
+ * @returns Object containing the total amount in token units and USD value
401
+ */
402
+ getTVL(): Promise<{
403
+ amount: Web3Number;
404
+ usdValue: number;
405
+ }>;
406
+ /**
407
+ * Retrieves the list of allowed pools and their detailed information from multiple sources:
408
+ * 1. Contract's allowed pools
409
+ * 2. Vesu positions API for current positions
410
+ * 3. Vesu pools API for APY and utilization data
411
+ *
412
+ * @returns {Promise<{
413
+ * data: Array<PoolInfoFull>,
414
+ * isErrorPositionsAPI: boolean
415
+ * }>} Object containing:
416
+ * - data: Array of pool information including IDs, weights, amounts, APYs and utilization
417
+ * - isErrorPositionsAPI: Boolean indicating if there was an error fetching position data
418
+ */
419
+ getPools(): Promise<{
420
+ data: {
421
+ pool_id: ContractAddr;
422
+ pool_name: any;
423
+ max_weight: number;
424
+ current_weight: number;
425
+ v_token: ContractAddr;
426
+ amount: Web3Number;
427
+ usdValue: Web3Number;
428
+ APY: {
429
+ baseApy: number;
430
+ defiSpringApy: number;
431
+ netApy: number;
432
+ };
433
+ currentUtilization: number;
434
+ maxUtilization: number;
435
+ }[];
436
+ isErrorPositionsAPI: boolean;
437
+ isErrorPoolsAPI: boolean;
438
+ isError: boolean;
439
+ }>;
440
+ /**
441
+ * Calculates the weighted average APY across all pools based on USD value.
442
+ * @returns {Promise<number>} The weighted average APY across all pools
443
+ */
444
+ netAPY(): Promise<number>;
445
+ /**
446
+ * Calculates the weighted average APY across all pools based on USD value.
447
+ * @returns {Promise<number>} The weighted average APY across all pools
448
+ */
449
+ netAPYGivenPools(pools: PoolInfoFull[]): number;
450
+ /**
451
+ * Calculates optimal position changes to maximize APY while respecting max weights.
452
+ * The algorithm:
453
+ * 1. Sorts pools by APY (highest first)
454
+ * 2. Calculates target amounts based on max weights
455
+ * 3. For each pool that needs more funds:
456
+ * - Takes funds from lowest APY pools that are over their target
457
+ * 4. Validates that total assets remain constant
458
+ *
459
+ * @returns {Promise<{
460
+ * changes: Change[],
461
+ * finalPools: PoolInfoFull[],
462
+ * isAnyPoolOverMaxWeight: boolean
463
+ * }>} Object containing:
464
+ * - changes: Array of position changes
465
+ * - finalPools: Array of pool information after rebalance
466
+ * @throws Error if rebalance is not possible while maintaining constraints
467
+ */
468
+ getRebalancedPositions(): Promise<{
469
+ changes: never[];
470
+ finalPools: never[];
471
+ isAnyPoolOverMaxWeight?: undefined;
472
+ } | {
473
+ changes: Change[];
474
+ finalPools: PoolInfoFull[];
475
+ isAnyPoolOverMaxWeight: boolean;
476
+ }>;
477
+ /**
478
+ * Creates a rebalance Call object for the strategy contract
479
+ * @param pools - Array of pool information including IDs, weights, amounts, APYs and utilization
480
+ * @returns Populated contract call for rebalance
481
+ */
482
+ getRebalanceCall(pools: Awaited<ReturnType<typeof this.getRebalancedPositions>>['changes'], isOverWeightAdjustment: boolean): Promise<starknet.Call | null>;
483
+ getInvestmentFlows(pools: PoolInfoFull[]): Promise<IInvestmentFlow[]>;
484
+ }
485
+ /**
486
+ * Represents the Vesu Rebalance Strategies.
487
+ */
488
+ declare const VesuRebalanceStrategies: IStrategyMetadata[];
489
+
261
490
  declare class TelegramNotif {
262
491
  private subscribers;
263
492
  readonly bot: TelegramBot;
@@ -266,6 +495,27 @@ declare class TelegramNotif {
266
495
  sendMessage(msg: string): void;
267
496
  }
268
497
 
498
+ type RequiredFields<T> = {
499
+ [K in keyof T]-?: T[K];
500
+ };
501
+ type RequiredKeys<T> = {
502
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
503
+ }[keyof T];
504
+ declare function assert(condition: boolean, message: string): void;
505
+
506
+ declare class PricerRedis extends Pricer {
507
+ private redisClient;
508
+ constructor(config: IConfig, tokens: TokenInfo[]);
509
+ /** Reads prices from Pricer._loadPrices and uses a callback to set prices in redis */
510
+ startWithRedis(redisUrl: string): Promise<void>;
511
+ close(): Promise<void>;
512
+ initRedis(redisUrl: string): Promise<void>;
513
+ /** sets current local price in redis */
514
+ private _setRedisPrices;
515
+ /** Returns price from redis */
516
+ getPrice(tokenSymbol: string): Promise<PriceInfo>;
517
+ }
518
+
269
519
  /**
270
520
  * @description Config to manage storage of files on disk
271
521
  * @param SECRET_FILE_FOLDER - Folder to store secret files (default: ~/.starknet-store)
@@ -344,24 +594,4 @@ declare class PasswordJsonCryptoUtil {
344
594
  decrypt(encryptedData: string, password: string): any;
345
595
  }
346
596
 
347
- type RequiredFields<T> = {
348
- [K in keyof T]-?: T[K];
349
- };
350
- type RequiredKeys<T> = {
351
- [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
352
- }[keyof T];
353
-
354
- declare class PricerRedis extends Pricer {
355
- private redisClient;
356
- constructor(config: IConfig, tokens: TokenInfo[]);
357
- /** Reads prices from Pricer._loadPrices and uses a callback to set prices in redis */
358
- startWithRedis(redisUrl: string): Promise<void>;
359
- close(): Promise<void>;
360
- initRedis(redisUrl: string): Promise<void>;
361
- /** sets current local price in redis */
362
- private _setRedisPrices;
363
- /** Returns price from redis */
364
- getPrice(tokenSymbol: string): Promise<PriceInfo>;
365
- }
366
-
367
- export { type AccountInfo, type AllAccountsStore, AutoCompounderSTRK, ContractAddr, FatalError, Global, type IConfig, ILending, type ILendingMetadata, type ILendingPosition, Initializable, type LendingToken, MarginType, Network, PasswordJsonCryptoUtil, Pragma, type PriceInfo, Pricer, PricerRedis, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, Store, type StoreConfig, TelegramNotif, type TokenInfo, Web3Number, ZkLend, getDefaultStoreConfig, getMainnetConfig, logger };
597
+ export { type AccountInfo, type AllAccountsStore, AutoCompounderSTRK, ContractAddr, FatalError, Global, type IConfig, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, Initializable, type LendingToken, MarginType, Network, PasswordJsonCryptoUtil, Pragma, type PriceInfo, Pricer, PricerFromApi, PricerRedis, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, Store, type StoreConfig, TelegramNotif, type TokenInfo, VesuRebalance, VesuRebalanceStrategies, Web3Number, ZkLend, assert, getDefaultStoreConfig, getMainnetConfig, logger };