@strkfarm/sdk 1.0.10 → 1.0.12

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.
@@ -35038,11 +35038,14 @@ var strkfarm_risk_engine = (() => {
35038
35038
  constructor(config2, tokens2) {
35039
35039
  this.tokens = [];
35040
35040
  this.prices = {};
35041
+ // code populates this map during runtime to determine which method to use for a given token
35042
+ // The method set will be the first one to try after first attempt
35043
+ this.methodToUse = {};
35041
35044
  /**
35042
35045
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
35043
35046
  */
35044
35047
  this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
35045
- this.EKUBO_API = "https://mainnet-api.ekubo.org/quote/{{AMOUNT}}/{{TOKEN_SYMBOL}}/USDC";
35048
+ this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8";
35046
35049
  // e.g. ETH/USDC
35047
35050
  // backup oracle001
35048
35051
  this.client = new CoinMarketCap(process.env.COINMARKETCAP_KEY);
@@ -35136,20 +35139,41 @@ var strkfarm_risk_engine = (() => {
35136
35139
  });
35137
35140
  }
35138
35141
  }
35139
- async _getPrice(token) {
35140
- try {
35141
- return await this._getPriceCoinbase(token);
35142
- } catch (error2) {
35143
- }
35144
- try {
35145
- return await this._getPriceCoinMarketCap(token);
35146
- } catch (error2) {
35142
+ async _getPrice(token, defaultMethod = "all") {
35143
+ const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
35144
+ logger.info(`Fetching price of ${token.symbol} using ${methodToUse}`);
35145
+ switch (methodToUse) {
35146
+ case "Coinbase":
35147
+ try {
35148
+ const result = await this._getPriceCoinbase(token);
35149
+ this.methodToUse[token.symbol] = "Coinbase";
35150
+ return result;
35151
+ } catch (error2) {
35152
+ console.warn(`Coinbase: price err: message [${token.symbol}]: `, error2.message);
35153
+ }
35154
+ case "Coinmarketcap":
35155
+ try {
35156
+ const result = await this._getPriceCoinMarketCap(token);
35157
+ this.methodToUse[token.symbol] = "Coinmarketcap";
35158
+ return result;
35159
+ } catch (error2) {
35160
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error2));
35161
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error2.message);
35162
+ }
35163
+ case "Ekubo":
35164
+ try {
35165
+ const result = await this._getPriceEkubo(token);
35166
+ this.methodToUse[token.symbol] = "Ekubo";
35167
+ return result;
35168
+ } catch (error2) {
35169
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error2.message);
35170
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error2));
35171
+ }
35147
35172
  }
35148
- try {
35149
- return await this._getPriceEkubo(token);
35150
- } catch (error2) {
35173
+ if (defaultMethod == "all") {
35174
+ return await this._getPrice(token, "Coinbase");
35151
35175
  }
35152
- throw new FatalError(`Price not found for ${token.name}`);
35176
+ throw new FatalError(`Price not found for ${token.symbol}`);
35153
35177
  }
35154
35178
  async _getPriceCoinbase(token) {
35155
35179
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
@@ -35159,19 +35183,21 @@ var strkfarm_risk_engine = (() => {
35159
35183
  }
35160
35184
  async _getPriceCoinMarketCap(token) {
35161
35185
  const result = await this.client.getQuotes({ symbol: token.symbol });
35162
- return result.data[token.symbol].quote.USD.price;
35186
+ if (result.data)
35187
+ return result.data[token.symbol].quote.USD.price;
35188
+ throw new Error(result);
35163
35189
  }
35164
35190
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
35165
- const url = this.EKUBO_API.replace("{{TOKEN_SYMBOL}}", token.symbol).replace("{{AMOUNT}}", amountIn.toWei());
35191
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address).replace("{{AMOUNT}}", amountIn.toWei());
35166
35192
  const result = await axios_default.get(url);
35167
35193
  const data = result.data;
35168
- const outputUSDC = Number(Web3Number.fromWei(data.total, 6).toFixed(6));
35194
+ const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6));
35169
35195
  logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
35170
35196
  if (outputUSDC === 0 && retry < 3) {
35171
35197
  const amountIn2 = new Web3Number(100, token.decimals);
35172
35198
  return await this._getPriceEkubo(token, amountIn2, retry + 1);
35173
35199
  }
35174
- const usdcPrice = (await this.getPrice("USDC")).price;
35200
+ const usdcPrice = 1;
35175
35201
  logger.verbose(`USDC Price: ${usdcPrice}`);
35176
35202
  return outputUSDC * usdcPrice;
35177
35203
  }
package/dist/index.d.ts CHANGED
@@ -59,6 +59,7 @@ declare class Pricer {
59
59
  protected prices: {
60
60
  [key: string]: PriceInfo;
61
61
  };
62
+ private methodToUse;
62
63
  /**
63
64
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
64
65
  */
@@ -73,7 +74,7 @@ declare class Pricer {
73
74
  assertNotStale(timestamp: Date, tokenName: string): void;
74
75
  getPrice(tokenName: string): Promise<PriceInfo>;
75
76
  protected _loadPrices(onUpdate?: (tokenSymbol: string) => void): void;
76
- _getPrice(token: TokenInfo): Promise<number>;
77
+ _getPrice(token: TokenInfo, defaultMethod?: string): Promise<number>;
77
78
  _getPriceCoinbase(token: TokenInfo): Promise<number>;
78
79
  _getPriceCoinMarketCap(token: TokenInfo): Promise<number>;
79
80
  _getPriceEkubo(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
package/dist/index.js CHANGED
@@ -181,11 +181,14 @@ var Pricer = class {
181
181
  constructor(config, tokens2) {
182
182
  this.tokens = [];
183
183
  this.prices = {};
184
+ // code populates this map during runtime to determine which method to use for a given token
185
+ // The method set will be the first one to try after first attempt
186
+ this.methodToUse = {};
184
187
  /**
185
188
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
186
189
  */
187
190
  this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
188
- this.EKUBO_API = "https://mainnet-api.ekubo.org/quote/{{AMOUNT}}/{{TOKEN_SYMBOL}}/USDC";
191
+ this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8";
189
192
  // e.g. ETH/USDC
190
193
  // backup oracle001
191
194
  this.client = new CoinMarketCap(process.env.COINMARKETCAP_KEY);
@@ -279,20 +282,41 @@ var Pricer = class {
279
282
  });
280
283
  }
281
284
  }
282
- async _getPrice(token) {
283
- try {
284
- return await this._getPriceCoinbase(token);
285
- } catch (error) {
286
- }
287
- try {
288
- return await this._getPriceCoinMarketCap(token);
289
- } catch (error) {
285
+ async _getPrice(token, defaultMethod = "all") {
286
+ const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
287
+ logger.info(`Fetching price of ${token.symbol} using ${methodToUse}`);
288
+ switch (methodToUse) {
289
+ case "Coinbase":
290
+ try {
291
+ const result = await this._getPriceCoinbase(token);
292
+ this.methodToUse[token.symbol] = "Coinbase";
293
+ return result;
294
+ } catch (error) {
295
+ console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
296
+ }
297
+ case "Coinmarketcap":
298
+ try {
299
+ const result = await this._getPriceCoinMarketCap(token);
300
+ this.methodToUse[token.symbol] = "Coinmarketcap";
301
+ return result;
302
+ } catch (error) {
303
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
304
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
305
+ }
306
+ case "Ekubo":
307
+ try {
308
+ const result = await this._getPriceEkubo(token);
309
+ this.methodToUse[token.symbol] = "Ekubo";
310
+ return result;
311
+ } catch (error) {
312
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
313
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
314
+ }
290
315
  }
291
- try {
292
- return await this._getPriceEkubo(token);
293
- } catch (error) {
316
+ if (defaultMethod == "all") {
317
+ return await this._getPrice(token, "Coinbase");
294
318
  }
295
- throw new FatalError(`Price not found for ${token.name}`);
319
+ throw new FatalError(`Price not found for ${token.symbol}`);
296
320
  }
297
321
  async _getPriceCoinbase(token) {
298
322
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
@@ -302,19 +326,21 @@ var Pricer = class {
302
326
  }
303
327
  async _getPriceCoinMarketCap(token) {
304
328
  const result = await this.client.getQuotes({ symbol: token.symbol });
305
- return result.data[token.symbol].quote.USD.price;
329
+ if (result.data)
330
+ return result.data[token.symbol].quote.USD.price;
331
+ throw new Error(result);
306
332
  }
307
333
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
308
- const url = this.EKUBO_API.replace("{{TOKEN_SYMBOL}}", token.symbol).replace("{{AMOUNT}}", amountIn.toWei());
334
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address).replace("{{AMOUNT}}", amountIn.toWei());
309
335
  const result = await import_axios2.default.get(url);
310
336
  const data = result.data;
311
- const outputUSDC = Number(Web3Number.fromWei(data.total, 6).toFixed(6));
337
+ const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6));
312
338
  logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
313
339
  if (outputUSDC === 0 && retry < 3) {
314
340
  const amountIn2 = new Web3Number(100, token.decimals);
315
341
  return await this._getPriceEkubo(token, amountIn2, retry + 1);
316
342
  }
317
- const usdcPrice = (await this.getPrice("USDC")).price;
343
+ const usdcPrice = 1;
318
344
  logger.verbose(`USDC Price: ${usdcPrice}`);
319
345
  return outputUSDC * usdcPrice;
320
346
  }
package/dist/index.mjs CHANGED
@@ -134,11 +134,14 @@ var Pricer = class {
134
134
  constructor(config, tokens2) {
135
135
  this.tokens = [];
136
136
  this.prices = {};
137
+ // code populates this map during runtime to determine which method to use for a given token
138
+ // The method set will be the first one to try after first attempt
139
+ this.methodToUse = {};
137
140
  /**
138
141
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
139
142
  */
140
143
  this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
141
- this.EKUBO_API = "https://mainnet-api.ekubo.org/quote/{{AMOUNT}}/{{TOKEN_SYMBOL}}/USDC";
144
+ this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8";
142
145
  // e.g. ETH/USDC
143
146
  // backup oracle001
144
147
  this.client = new CoinMarketCap(process.env.COINMARKETCAP_KEY);
@@ -232,20 +235,41 @@ var Pricer = class {
232
235
  });
233
236
  }
234
237
  }
235
- async _getPrice(token) {
236
- try {
237
- return await this._getPriceCoinbase(token);
238
- } catch (error) {
239
- }
240
- try {
241
- return await this._getPriceCoinMarketCap(token);
242
- } catch (error) {
238
+ async _getPrice(token, defaultMethod = "all") {
239
+ const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
240
+ logger.info(`Fetching price of ${token.symbol} using ${methodToUse}`);
241
+ switch (methodToUse) {
242
+ case "Coinbase":
243
+ try {
244
+ const result = await this._getPriceCoinbase(token);
245
+ this.methodToUse[token.symbol] = "Coinbase";
246
+ return result;
247
+ } catch (error) {
248
+ console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
249
+ }
250
+ case "Coinmarketcap":
251
+ try {
252
+ const result = await this._getPriceCoinMarketCap(token);
253
+ this.methodToUse[token.symbol] = "Coinmarketcap";
254
+ return result;
255
+ } catch (error) {
256
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
257
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
258
+ }
259
+ case "Ekubo":
260
+ try {
261
+ const result = await this._getPriceEkubo(token);
262
+ this.methodToUse[token.symbol] = "Ekubo";
263
+ return result;
264
+ } catch (error) {
265
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
266
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
267
+ }
243
268
  }
244
- try {
245
- return await this._getPriceEkubo(token);
246
- } catch (error) {
269
+ if (defaultMethod == "all") {
270
+ return await this._getPrice(token, "Coinbase");
247
271
  }
248
- throw new FatalError(`Price not found for ${token.name}`);
272
+ throw new FatalError(`Price not found for ${token.symbol}`);
249
273
  }
250
274
  async _getPriceCoinbase(token) {
251
275
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
@@ -255,19 +279,21 @@ var Pricer = class {
255
279
  }
256
280
  async _getPriceCoinMarketCap(token) {
257
281
  const result = await this.client.getQuotes({ symbol: token.symbol });
258
- return result.data[token.symbol].quote.USD.price;
282
+ if (result.data)
283
+ return result.data[token.symbol].quote.USD.price;
284
+ throw new Error(result);
259
285
  }
260
286
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
261
- const url = this.EKUBO_API.replace("{{TOKEN_SYMBOL}}", token.symbol).replace("{{AMOUNT}}", amountIn.toWei());
287
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address).replace("{{AMOUNT}}", amountIn.toWei());
262
288
  const result = await axios2.get(url);
263
289
  const data = result.data;
264
- const outputUSDC = Number(Web3Number.fromWei(data.total, 6).toFixed(6));
290
+ const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6));
265
291
  logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
266
292
  if (outputUSDC === 0 && retry < 3) {
267
293
  const amountIn2 = new Web3Number(100, token.decimals);
268
294
  return await this._getPriceEkubo(token, amountIn2, retry + 1);
269
295
  }
270
- const usdcPrice = (await this.getPrice("USDC")).price;
296
+ const usdcPrice = 1;
271
297
  logger.verbose(`USDC Price: ${usdcPrice}`);
272
298
  return outputUSDC * usdcPrice;
273
299
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
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
  "main": "dist/index.js",
@@ -53,6 +53,7 @@
53
53
  "inquirer": "^10.1.2",
54
54
  "node-telegram-bot-api": "^0.66.0",
55
55
  "redis": "^4.7.0",
56
+ "stacktrace-js": "^2.0.2",
56
57
  "starknet": "^6.11.0",
57
58
  "winston": "^3.13.0"
58
59
  }
@@ -16,15 +16,19 @@ export class Pricer {
16
16
  [key: string]: PriceInfo
17
17
  } = {}
18
18
 
19
+ // code populates this map during runtime to determine which method to use for a given token
20
+ // The method set will be the first one to try after first attempt
21
+ private methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap'} = {};
22
+
19
23
  /**
20
24
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
21
25
  */
22
26
  protected PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
23
- protected EKUBO_API = 'https://mainnet-api.ekubo.org/quote/{{AMOUNT}}/{{TOKEN_SYMBOL}}/USDC'; // e.g. ETH/USDC
27
+ protected EKUBO_API = 'https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8'; // e.g. ETH/USDC
24
28
 
25
29
  // backup oracle001
26
30
  protected client = new CoinMarketCap(process.env.COINMARKETCAP_KEY!);
27
-
31
+
28
32
  constructor(config: IConfig, tokens: TokenInfo[]) {
29
33
  this.config = config;
30
34
  this.tokens = tokens;
@@ -125,45 +129,69 @@ export class Pricer {
125
129
  }
126
130
  }
127
131
 
128
- async _getPrice(token: TokenInfo) {
129
- try {
130
- return await this._getPriceCoinbase(token);
131
- } catch (error) {
132
- // do nothing, try next
133
- }
134
-
135
- try {
136
- return await this._getPriceCoinMarketCap(token);
137
- } catch (error) {
138
- // do nothing, try next
132
+ async _getPrice(token: TokenInfo, defaultMethod = 'all'): Promise<number> {
133
+ const methodToUse: string = this.methodToUse[token.symbol] || defaultMethod; // default start with coinbase
134
+ logger.info(`Fetching price of ${token.symbol} using ${methodToUse}`);
135
+ switch (methodToUse) {
136
+ case 'Coinbase':
137
+ try {
138
+ const result = await this._getPriceCoinbase(token);
139
+ this.methodToUse[token.symbol] = 'Coinbase';
140
+ return result;
141
+ } catch (error: any) {
142
+ console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
143
+ // do nothing, try next
144
+ }
145
+ case 'Coinmarketcap':
146
+ try {
147
+ const result = await this._getPriceCoinMarketCap(token);
148
+ this.methodToUse[token.symbol] = 'Coinmarketcap';
149
+ return result;
150
+ } catch (error: any) {
151
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
152
+ console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
153
+ }
154
+ case 'Ekubo':
155
+ try {
156
+ const result = await this._getPriceEkubo(token);
157
+ this.methodToUse[token.symbol] = 'Ekubo';
158
+ return result;
159
+ } catch (error: any) {
160
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
161
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
162
+ // do nothing, try next
163
+ }
139
164
  }
140
165
 
141
- try {
142
- return await this._getPriceEkubo(token);
143
- } catch (error) {
144
- // do nothing, try next
166
+ // if methodToUse is the default one, pass Coinbase to try all from start
167
+ if (defaultMethod == 'all') {
168
+ // try again with coinbase
169
+ return await this._getPrice(token, 'Coinbase');
145
170
  }
146
171
 
147
- throw new FatalError(`Price not found for ${token.name}`);
172
+ throw new FatalError(`Price not found for ${token.symbol}`);
148
173
  }
149
174
 
150
175
  async _getPriceCoinbase(token: TokenInfo) {
151
176
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
152
- const result = await axios.get(url);
177
+ const result = await axios.get(url)
153
178
  const data: any = result.data;
154
179
  return Number(data.data.amount);
155
180
  }
156
181
 
157
182
  async _getPriceCoinMarketCap(token: TokenInfo): Promise<number> {
158
183
  const result = await this.client.getQuotes({symbol: token.symbol});
159
- return result.data[token.symbol].quote.USD.price as number
184
+ if (result.data)
185
+ return result.data[token.symbol].quote.USD.price as number
186
+
187
+ throw new Error(result);
160
188
  }
161
189
 
162
190
  async _getPriceEkubo(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
163
- const url = this.EKUBO_API.replace("{{TOKEN_SYMBOL}}", token.symbol).replace("{{AMOUNT}}", amountIn.toWei());
191
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address).replace("{{AMOUNT}}", amountIn.toWei());
164
192
  const result = await axios.get(url);
165
193
  const data: any = result.data;
166
- const outputUSDC = Number(Web3Number.fromWei(data.total, 6).toFixed(6));
194
+ const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6));
167
195
  logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
168
196
  if (outputUSDC === 0 && retry < 3) {
169
197
  // try again with a higher amount
@@ -174,7 +202,7 @@ export class Pricer {
174
202
  // if usdc depegs, it will not longer be 1 USD
175
203
  // so we need to get the price of USDC in USD
176
204
  // and then convert the outputUSDC to USD
177
- const usdcPrice = (await this.getPrice('USDC')).price;
205
+ const usdcPrice = 1; // (await this.getPrice('USDC')).price;
178
206
  logger.verbose(`USDC Price: ${usdcPrice}`);
179
207
  return outputUSDC * usdcPrice;
180
208
  }