@strkfarm/sdk 1.1.4 → 1.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
5
5
  "typings": "dist/index.d.ts",
6
6
  "types": "dist/index.d.ts",
@@ -60,6 +60,7 @@
60
60
  "@avnu/avnu-sdk": "3.0.2",
61
61
  "@ericnordelo/strk-merkle-tree": "^1.0.0",
62
62
  "@noble/curves": "^1.9.7",
63
+ "@noble/hashes": "^2.0.0",
63
64
  "@scure/starknet": "^2.0.0",
64
65
  "bignumber.js": "4.0.4",
65
66
  "browser-assert": "^1.2.1",
package/src/global.ts CHANGED
@@ -63,7 +63,7 @@ const defaultTokens: TokenInfo[] = [{
63
63
  name: 'WBTC',
64
64
  symbol: 'WBTC',
65
65
  logo: 'https://assets.troves.fi/integrations/tokens/wbtc.svg',
66
- address: ContractAddr.from('0x3fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac'),
66
+ address: ContractAddr.from('0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac'),
67
67
  decimals: 8,
68
68
  coingeckId: undefined,
69
69
  displayDecimals: 6,
@@ -77,6 +77,56 @@ const defaultTokens: TokenInfo[] = [{
77
77
  coingeckId: undefined,
78
78
  displayDecimals: 6,
79
79
  priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
80
+ }, {
81
+ name: 'solvBTC',
82
+ symbol: 'solvBTC',
83
+ logo: 'https://assets.strkfarm.com/integrations/tokens/solvbtc.svg',
84
+ address: ContractAddr.from('0x0593e034dda23eea82d2ba9a30960ed42cf4a01502cc2351dc9b9881f9931a68'),
85
+ decimals: 18,
86
+ coingeckId: undefined,
87
+ priceProxySymbol: 'WBTC',
88
+ displayDecimals: 6,
89
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
90
+ }, {
91
+ name: 'LBTC',
92
+ symbol: 'LBTC',
93
+ logo: 'https://assets.strkfarm.com/integrations/tokens/lbtc.svg',
94
+ address: ContractAddr.from('0x036834a40984312f7f7de8d31e3f6305b325389eaeea5b1c0664b2fb936461a4'),
95
+ decimals: 8,
96
+ coingeckId: undefined,
97
+ displayDecimals: 6,
98
+ priceProxySymbol: 'WBTC',
99
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
100
+ }, {
101
+ name: 'xWBTC',
102
+ symbol: 'xWBTC',
103
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xwbtc.svg',
104
+ address: ContractAddr.from('0x6a567e68c805323525fe1649adb80b03cddf92c23d2629a6779f54192dffc13'),
105
+ decimals: 8,
106
+ coingeckId: undefined,
107
+ displayDecimals: 6,
108
+ priceProxySymbol: 'WBTC',
109
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
110
+ }, {
111
+ name: 'xsBTC',
112
+ symbol: 'xsBTC',
113
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xsbtc_solv.svg',
114
+ address: ContractAddr.from('0x580f3dc564a7b82f21d40d404b3842d490ae7205e6ac07b1b7af2b4a5183dc9'),
115
+ decimals: 18,
116
+ coingeckId: undefined,
117
+ displayDecimals: 6,
118
+ priceProxySymbol: 'WBTC',
119
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
120
+ }, {
121
+ name: 'xtBTC',
122
+ symbol: 'xtBTC',
123
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xtbtc.svg',
124
+ address: ContractAddr.from('0x43a35c1425a0125ef8c171f1a75c6f31ef8648edcc8324b55ce1917db3f9b91'),
125
+ decimals: 8,
126
+ coingeckId: undefined,
127
+ displayDecimals: 6,
128
+ priceProxySymbol: 'WBTC',
129
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
80
130
  }]
81
131
  const tokens: TokenInfo[] = defaultTokens;
82
132
 
@@ -33,6 +33,7 @@ export interface TokenInfo {
33
33
  logo: string;
34
34
  coingeckId?: string;
35
35
  displayDecimals: number;
36
+ priceProxySymbol?: string; // for tokens like illiquid tokens, we use a proxy symbol to get the price
36
37
  priceCheckAmount?: number; // for tokens like BTC, doing 1BTC price check may not be ideal, esp on illiquid netwrks like sn
37
38
  }
38
39
 
@@ -95,6 +96,7 @@ export interface IStrategyMetadata<T> {
95
96
  points?: {multiplier: number, logo: string, toolTip?: string}[];
96
97
  docs?: string;
97
98
  investmentSteps: string[];
99
+ curator?: { name: string, logo: string }
98
100
  }
99
101
 
100
102
  export interface IInvestmentFlow {
@@ -0,0 +1,175 @@
1
+ import { RiskType } from "./common";
2
+
3
+ export enum MarketRiskLevel {
4
+ NO_RISK = 0,
5
+ VERY_LOW_VOLATILITY = 1,
6
+ LOW_VOLATILITY = 2,
7
+ MODERATE_VOLATILITY = 3,
8
+ HIGH_VOLATILITY = 4,
9
+ VERY_HIGH_VOLATILITY = 5
10
+ }
11
+
12
+ export enum ImpermanentLossLevel {
13
+ NO_RISK = 0,
14
+ HIGHLY_CORRELATED = 1, // e.g. xSTRK/STRK
15
+ CORRELATED = 2, // e.g. BTC/SOL
16
+ NON_CORRELATED = 3, // e.g. STRK/USDC
17
+ LEVERAGED_CORRELATED = 4, // Added leverage on correlated pairs
18
+ LEVERAGED_NON_CORRELATED = 5 // Added leverage on non-correlated pairs
19
+ }
20
+
21
+ export enum LiquidationRiskLevel {
22
+ NO_RISK = 0,
23
+ VERY_LOW_PROBABILITY = 1,
24
+ LOW_PROBABILITY = 2,
25
+ MODERATE_PROBABILITY = 3,
26
+ HIGH_PROBABILITY = 4,
27
+ CRITICAL_PROBABILITY = 5
28
+ }
29
+
30
+ export enum LowLiquidityRiskLevel {
31
+ HIGH_LIQUIDITY = 0,
32
+ GOOD_LIQUIDITY = 1,
33
+ ADEQUATE_LIQUIDITY = 2,
34
+ MODERATE_CONCERNS = 3,
35
+ LOW_LIQUIDITY = 4,
36
+ SEVERE_CONSTRAINTS = 5
37
+ }
38
+
39
+ export enum SmartContractRiskLevel {
40
+ NO_RISK = 0,
41
+ BATTLE_TESTED = 1, // Well-audited, battle-tested contracts
42
+ WELL_AUDITED = 2, // Audited contracts with good track record
43
+ RECENTLY_AUDITED = 3, // Recently audited or some complexity
44
+ UNAUDITED = 4, // Unaudited or complex logic
45
+ EXPERIMENTAL = 5 // Experimental or known vulnerabilities
46
+ }
47
+
48
+ export enum OracleRiskLevel {
49
+ NO_DEPENDENCY = 0,
50
+ MULTIPLE_RELIABLE = 1, // Multiple reliable oracles (Chainlink, etc.)
51
+ SINGLE_RELIABLE = 2, // Single reliable oracle
52
+ LESS_ESTABLISHED = 3, // Less established oracle
53
+ UNPROVEN = 4, // Custom or unproven oracle
54
+ UNRELIABLE = 5 // No oracle or highly unreliable
55
+ }
56
+
57
+ export enum TechnicalRiskLevel {
58
+ NO_RISK = 0,
59
+ STABLE_INFRASTRUCTURE = 1, // Stable, well-tested infrastructure
60
+ ESTABLISHED_PROTOCOLS = 2, // Established protocols
61
+ SOME_COMPLEXITY = 3, // Some technical complexity
62
+ NEW_IMPLEMENTATION = 4, // New or complex technical implementation
63
+ EXPERIMENTAL_TECHNOLOGY = 5 // Experimental or untested technology
64
+ }
65
+
66
+ export enum CounterpartyRiskLevel {
67
+ NO_RISK = 0,
68
+ FULLY_DECENTRALIZED = 1, // Decentralized, no counterparty
69
+ REPUTABLE_COUNTERPARTY = 2, // Established, reputable counterparty
70
+ SOME_EXPOSURE = 3, // Some counterparty exposure
71
+ SIGNIFICANT_RISK = 4, // Significant counterparty risk
72
+ BAD_DEBT_ISSUES = 5 // Bad debt or known issues
73
+ }
74
+
75
+ export enum DepegRiskLevel {
76
+ NO_RISK = 0,
77
+ HIGHLY_STABLE = 1, // Highly stable assets (e.g., major stablecoins)
78
+ GENERALLY_STABLE = 2, // Generally stable with minor fluctuations
79
+ OCCASIONAL_DEPEG = 3, // Occasional depeg events
80
+ FREQUENT_DEPEG = 4, // Frequent or significant depeg risk
81
+ HIGH_DEPEG_PROBABILITY = 5 // High probability of severe depeg (e.g., USDC depeg scenarios)
82
+ }
83
+
84
+ // Helper type to map risk types to their corresponding level enums
85
+ export type RiskLevelMap = {
86
+ [RiskType.MARKET_RISK]: MarketRiskLevel;
87
+ [RiskType.IMPERMANENT_LOSS]: ImpermanentLossLevel;
88
+ [RiskType.LIQUIDATION_RISK]: LiquidationRiskLevel;
89
+ [RiskType.LOW_LIQUIDITY_RISK]: LowLiquidityRiskLevel;
90
+ [RiskType.SMART_CONTRACT_RISK]: SmartContractRiskLevel;
91
+ [RiskType.ORACLE_RISK]: OracleRiskLevel;
92
+ [RiskType.TECHNICAL_RISK]: TechnicalRiskLevel;
93
+ [RiskType.COUNTERPARTY_RISK]: CounterpartyRiskLevel;
94
+ [RiskType.DEPEG_RISK]: DepegRiskLevel;
95
+ };
96
+
97
+ // Utility function to get risk level description
98
+ export function getRiskLevelDescription(riskType: RiskType, level: number): string {
99
+ const descriptions: Record<RiskType, Record<number, string>> = {
100
+ [RiskType.MARKET_RISK]: {
101
+ 0: "No market risk",
102
+ 1: "Very low market volatility",
103
+ 2: "Low market volatility",
104
+ 3: "Moderate market volatility",
105
+ 4: "High market volatility",
106
+ 5: "Very high market volatility"
107
+ },
108
+ [RiskType.IMPERMANENT_LOSS]: {
109
+ 0: "No impermanent loss risk",
110
+ 1: "Highly correlated pairs (minimal IL)",
111
+ 2: "Correlated pairs (low IL)",
112
+ 3: "Non-correlated pairs (moderate IL)",
113
+ 4: "Leveraged correlated pairs",
114
+ 5: "Leveraged non-correlated pairs"
115
+ },
116
+ [RiskType.LIQUIDATION_RISK]: {
117
+ 0: "No liquidation risk",
118
+ 1: "Very low liquidation probability",
119
+ 2: "Low liquidation probability",
120
+ 3: "Moderate liquidation risk",
121
+ 4: "High liquidation risk",
122
+ 5: "Critical liquidation risk"
123
+ },
124
+ [RiskType.LOW_LIQUIDITY_RISK]: {
125
+ 0: "High liquidity",
126
+ 1: "Good liquidity",
127
+ 2: "Adequate liquidity",
128
+ 3: "Moderate liquidity concerns",
129
+ 4: "Low liquidity",
130
+ 5: "Severe liquidity constraints"
131
+ },
132
+ [RiskType.SMART_CONTRACT_RISK]: {
133
+ 0: "No smart contract risk",
134
+ 1: "Battle-tested contracts",
135
+ 2: "Well-audited contracts",
136
+ 3: "Recently audited contracts",
137
+ 4: "Unaudited contracts",
138
+ 5: "Experimental or vulnerable contracts"
139
+ },
140
+ [RiskType.ORACLE_RISK]: {
141
+ 0: "No oracle dependency",
142
+ 1: "Multiple reliable oracles",
143
+ 2: "Single reliable oracle",
144
+ 3: "Less established oracle",
145
+ 4: "Unproven oracle",
146
+ 5: "Unreliable or no oracle"
147
+ },
148
+ [RiskType.TECHNICAL_RISK]: {
149
+ 0: "No technical risk",
150
+ 1: "Stable infrastructure",
151
+ 2: "Established protocols",
152
+ 3: "Some complexity",
153
+ 4: "New implementation",
154
+ 5: "Experimental technology"
155
+ },
156
+ [RiskType.COUNTERPARTY_RISK]: {
157
+ 0: "No counterparty risk",
158
+ 1: "Fully decentralized",
159
+ 2: "Reputable counterparty",
160
+ 3: "Some counterparty exposure",
161
+ 4: "Significant counterparty risk",
162
+ 5: "Bad debt or known issues"
163
+ },
164
+ [RiskType.DEPEG_RISK]: {
165
+ 0: "No depeg risk",
166
+ 1: "Highly stable asset",
167
+ 2: "Generally stable",
168
+ 3: "Occasional depeg events",
169
+ 4: "Frequent depeg risk",
170
+ 5: "High depeg probability"
171
+ }
172
+ };
173
+
174
+ return descriptions[riskType][level] || "Unknown risk level";
175
+ }
@@ -4,6 +4,7 @@ import { IConfig } from "@/interfaces";
4
4
  import { assert } from "@/utils";
5
5
  import { Contract, num } from "starknet";
6
6
  import { ERC20 } from "./erc20";
7
+ import { ENDPOINTS } from "@/strategies/constants";
7
8
 
8
9
  export interface HarvestInfo {
9
10
  rewardsContract: ContractAddr,
@@ -87,7 +88,7 @@ export const VESU_REWARDS_CONTRACT = ContractAddr.from('0x0387f3eb1d98632fbe3440
87
88
 
88
89
  export class VesuHarvests extends Harvests {
89
90
  async getHarvests(addr: ContractAddr): Promise<HarvestInfo[]> {
90
- const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
91
+ const result = await fetch(`${ENDPOINTS.VESU_BASE}/users/${addr.address}/strk-rewards/calldata`);
91
92
  const data = await result.json();
92
93
  const rewardsContract = VESU_REWARDS_CONTRACT;
93
94
 
@@ -16,6 +16,9 @@ export class Pricer extends PricerBase {
16
16
  [key: string]: PriceInfo
17
17
  } = {}
18
18
 
19
+ refreshInterval = 30000;
20
+ staleTime = 60000;
21
+
19
22
  // code populates this map during runtime to determine which method to use for a given token
20
23
  // The method set will be the first one to try after first attempt
21
24
  private methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap'} = {};
@@ -26,8 +29,10 @@ export class Pricer extends PricerBase {
26
29
  protected PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
27
30
  protected EKUBO_API = 'https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8'; // e.g. ETH/USDC
28
31
 
29
- constructor(config: IConfig, tokens: TokenInfo[]) {
32
+ constructor(config: IConfig, tokens: TokenInfo[], refreshInterval = 30000, staleTime = 60000) {
30
33
  super(config, tokens);
34
+ this.refreshInterval = refreshInterval;
35
+ this.staleTime = staleTime;
31
36
  }
32
37
 
33
38
  isReady() {
@@ -64,11 +69,11 @@ export class Pricer extends PricerBase {
64
69
  this._loadPrices();
65
70
  setInterval(() => {
66
71
  this._loadPrices();
67
- }, 30000);
72
+ }, this.refreshInterval);
68
73
  }
69
74
 
70
75
  isStale(timestamp: Date, tokenName: string) {
71
- const STALE_TIME = 60000;
76
+ const STALE_TIME = this.staleTime;
72
77
  return (new Date().getTime() - timestamp.getTime()) > STALE_TIME;
73
78
  }
74
79
 
@@ -97,13 +102,25 @@ export class Pricer extends PricerBase {
97
102
  return;
98
103
  }
99
104
 
100
- const price = await this._getPrice(token);
101
- this.prices[token.symbol] = {
102
- price,
103
- timestamp: new Date()
105
+ if (token.priceProxySymbol) {
106
+ const proxyToken = this.tokens.find(t => t.symbol === token.priceProxySymbol);
107
+ if (!proxyToken) {
108
+ throw new FatalError(`Price proxy token ${token.priceProxySymbol} not found`);
109
+ }
110
+ const price = await this._getPrice(proxyToken);
111
+ this.prices[token.symbol] = {
112
+ price,
113
+ timestamp: new Date()
114
+ }
115
+ } else {
116
+ const price = await this._getPrice(token);
117
+ this.prices[token.symbol] = {
118
+ price,
119
+ timestamp: new Date()
120
+ }
104
121
  }
105
122
  onUpdate(token.symbol);
106
- logger.verbose(`Fetched price of ${token.name} as ${price}`);
123
+ logger.verbose(`Fetched price of ${token.name} as ${this.prices[token.symbol].price}`);
107
124
  break;
108
125
  } catch (error: any) {
109
126
  if (retry < MAX_RETRIES) {
@@ -4,9 +4,9 @@ import { logger } from "@/utils/logger";
4
4
  export class TelegramNotif {
5
5
  private subscribers: string[] = [
6
6
  // '6820228303',
7
- '1505578076',
8
- '1356705582', // langs
9
- '1388729514', // hwashere
7
+ // '1505578076',
8
+ // '1356705582', // langs
9
+ // '1388729514', // hwashere
10
10
  '985902592'
11
11
  ];
12
12
  readonly bot: TelegramBot;
@@ -4,4 +4,8 @@ export const COMMON_CONTRACTS = [{
4
4
  address: ContractAddr.from("0x0636a3f51cc37f5729e4da4b1de6a8549a28f3c0d5bf3b17f150971e451ff9c2"),
5
5
  name: "Access Controller",
6
6
  sourceCodeUrl: "https://github.com/strkfarm/strkfarm-contracts/blob/main/src/components/accessControl.cairo",
7
- }];
7
+ }];
8
+
9
+ export const ENDPOINTS = {
10
+ VESU_BASE: "https://cache-server-t2me.onrender.com/vesu"
11
+ }