@strkfarm/sdk 1.0.18 → 1.0.20

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.
@@ -0,0 +1,53 @@
1
+ import BigNumber from "bignumber.js";
2
+
3
+ export class _Web3Number<T extends _Web3Number<T>> extends BigNumber {
4
+ decimals: number;
5
+
6
+ constructor(value: string | number, decimals: number) {
7
+ super(value);
8
+ this.decimals = decimals;
9
+ }
10
+
11
+ toWei() {
12
+ return this.mul(10 ** this.decimals).toFixed(0);
13
+ }
14
+
15
+ multipliedBy(value: string | number | T): T {
16
+ let _value = Number(value).toFixed(13);
17
+ return this.construct(this.mul(_value).toString(), this.decimals);
18
+ }
19
+
20
+ dividedBy(value: string | number | T): T {
21
+ let _value = Number(value).toFixed(13);
22
+ return this.construct(this.div(_value).toString(), this.decimals);
23
+ }
24
+
25
+ plus(value: string | number | T): T {
26
+ const _value = Number(value).toFixed(13);
27
+ return this.construct(this.add(_value).toString(), this.decimals);
28
+ }
29
+
30
+ minus(n: number | string | T, base?: number): T {
31
+ const _value = Number(n).toFixed(13);
32
+ return this.construct(super.minus(_value, base).toString(), this.decimals);
33
+ }
34
+
35
+ protected construct(value: string | number, decimals: number): T {
36
+ return new (this.constructor as { new (value: string | number, decimals: number): T })(value, decimals);
37
+ }
38
+
39
+ toString(base?: number | undefined): string {
40
+ return super.toString(base);
41
+ }
42
+
43
+ toJSON() {
44
+ return this.toString();
45
+ }
46
+
47
+ valueOf() {
48
+ return this.toString();
49
+ }
50
+ }
51
+
52
+ BigNumber.config({ DECIMAL_PLACES: 18 })
53
+ _Web3Number.config({ DECIMAL_PLACES: 18 })
@@ -35,4 +35,8 @@ export class ContractAddr {
35
35
  static eqString(a: string, b: string) {
36
36
  return ContractAddr.standardise(a) === ContractAddr.standardise(b);
37
37
  }
38
+
39
+ toString() {
40
+ return this.address;
41
+ }
38
42
  }
@@ -0,0 +1,8 @@
1
+ import { _Web3Number } from "./_bignumber";
2
+
3
+ export class Web3Number extends _Web3Number<Web3Number> {
4
+ static fromWei(weiNumber: string | number, decimals: number) {
5
+ const bn = (new Web3Number(weiNumber, decimals)).dividedBy(10 ** decimals)
6
+ return new Web3Number(bn.toString(), decimals);
7
+ }
8
+ }
@@ -0,0 +1,22 @@
1
+ import util from 'util';
2
+ import { _Web3Number } from "./_bignumber";
3
+
4
+ export class Web3Number extends _Web3Number<Web3Number> {
5
+
6
+ static fromWei(weiNumber: string | number, decimals: number) {
7
+ const bn = (new Web3Number(weiNumber, decimals)).dividedBy(10 ** decimals)
8
+ return new Web3Number(bn.toString(), decimals);
9
+ }
10
+
11
+ [util.inspect.custom](depth: any, opts: any): string {
12
+ return this.toString();
13
+ }
14
+
15
+ [Symbol.for('nodejs.util.inspect.custom')](depth: any, inspectOptions: any, inspect: any): string {
16
+ return this.toString();
17
+ }
18
+
19
+ inspect(depth: any, opts: any) {
20
+ return this.toString();
21
+ }
22
+ }
@@ -1,55 +1 @@
1
- import BigNumber from "bignumber.js";
2
- // import { inspect } from 'util';
3
- // const customInspectSymbol = inspect.custom || Symbol.for('nodejs.util.inspect.custom');
4
-
5
- function isNode() {
6
- // Check for the presence of the `window` object, which is undefined in Node.js
7
- return typeof window === 'undefined';
8
- }
9
-
10
- export class Web3Number extends BigNumber {
11
- decimals: number;
12
-
13
- constructor(value: string | number, decimals: number) {
14
- super(value);
15
- this.decimals = decimals;
16
- }
17
-
18
- static fromWei(weiNumber: string | number, decimals: number) {
19
- const bn = (new Web3Number(weiNumber, decimals)).dividedBy(10 ** decimals)
20
- return new Web3Number(bn.toString(), decimals);
21
- }
22
-
23
- toWei() {
24
- return this.mul(10 ** this.decimals).toFixed(0);
25
- }
26
-
27
- multipliedBy(value: string | number) {
28
- let _value = Number(value).toFixed(6);
29
- return new Web3Number(this.mul(_value).toString(), this.decimals);
30
- }
31
-
32
- dividedBy(value: string | number) {
33
- let _value = Number(value).toFixed(6);
34
- return new Web3Number(this.div(_value).toString(), this.decimals);
35
- }
36
-
37
- plus(value: string | number) {
38
- return new Web3Number(this.add(value).toString(), this.decimals);
39
- }
40
-
41
- minus(n: number | string, base?: number): Web3Number {
42
- return new Web3Number(super.minus(n, base).toString(), this.decimals);
43
- }
44
-
45
- toString(base?: number | undefined): string {
46
- return super.toString(base);
47
- }
48
-
49
- // [customInspectSymbol](depth: any, inspectOptions: any, inspect: any) {
50
- // return this.toString();
51
- // }
52
- }
53
-
54
- BigNumber.config({ DECIMAL_PLACES: 18 })
55
- Web3Number.config({ DECIMAL_PLACES: 18 })
1
+ export * from '@/dataTypes/bignumber.browser';
@@ -1,2 +1,2 @@
1
- export * from './bignumber';
1
+ export * from '@/dataTypes/bignumber';
2
2
  export * from './address';
package/src/global.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import axios from 'axios';
2
2
  import { TokenInfo } from './interfaces';
3
+ import { ContractAddr } from './dataTypes';
3
4
 
4
5
  const colors = {
5
6
  error: 'red',
@@ -45,14 +46,50 @@ export class FatalError extends Error {
45
46
  }
46
47
  }
47
48
 
48
- const tokens: TokenInfo[] = [{
49
+ const defaultTokens: TokenInfo[] = [{
49
50
  name: 'Starknet',
50
51
  symbol: 'STRK',
51
52
  logo: 'https://assets.coingecko.com/coins/images/26433/small/starknet.png',
52
- address: '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
53
+ address: ContractAddr.from('0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d'),
53
54
  decimals: 18,
54
55
  coingeckId: 'starknet'
55
- }];
56
+ }, {
57
+ name: 'xSTRK',
58
+ symbol: 'xSTRK',
59
+ logo: 'https://dashboard.endur.fi/endur-fi.svg',
60
+ address: ContractAddr.from('0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a'),
61
+ decimals: 18,
62
+ coingeckId: undefined
63
+ }, {
64
+ name: 'ETH',
65
+ symbol: 'ETH',
66
+ logo: 'https://opbnb.bscscan.com/token/images/ether.svg',
67
+ address: ContractAddr.from('0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7'),
68
+ decimals: 18,
69
+ coingeckId: undefined
70
+ }, {
71
+ name: 'USDC',
72
+ symbol: 'USDC',
73
+ logo: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png',
74
+ address: ContractAddr.from('0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8'),
75
+ decimals: 6,
76
+ coingeckId: undefined
77
+ }, {
78
+ name: 'USDT',
79
+ symbol: 'USDT',
80
+ logo: 'https://assets.coingecko.com/coins/images/325/small/Tether.png',
81
+ address: ContractAddr.from('0x68f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8'),
82
+ decimals: 6,
83
+ coingeckId: undefined
84
+ }, {
85
+ name: 'WBTC',
86
+ symbol: 'WBTC',
87
+ logo: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/logo.png',
88
+ address: ContractAddr.from('0x3fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac'),
89
+ decimals: 8,
90
+ coingeckId: undefined
91
+ }]
92
+ const tokens: TokenInfo[] = defaultTokens;
56
93
 
57
94
  /** Contains globally useful functions.
58
95
  * - fatalError: Things to do when a fatal error occurs
@@ -109,7 +146,7 @@ export class Global {
109
146
  tokens.push({
110
147
  name: token.name,
111
148
  symbol: token.symbol,
112
- address: token.address,
149
+ address: ContractAddr.from(token.address),
113
150
  decimals: token.decimals,
114
151
  logo: token.logoUri,
115
152
  coingeckId: token.extensions.coingeckoId,
@@ -124,4 +161,17 @@ export class Global {
124
161
  throw new FatalError(message);
125
162
  }
126
163
  }
164
+
165
+ static async getTokenInfoFromAddr(addr: ContractAddr) {
166
+ // if tokens are not loaded, load them
167
+ if (tokens.length == defaultTokens.length) {
168
+ await Global.getTokens();
169
+ }
170
+
171
+ const token = tokens.find((token) => addr.eq(token.address));
172
+ if (!token) {
173
+ throw new FatalError(`Token not found: ${addr.address}`);
174
+ }
175
+ return token;
176
+ }
127
177
  }
@@ -2,12 +2,18 @@ import { ContractAddr, Web3Number } from "@/dataTypes"
2
2
  import { BlockIdentifier, RpcProvider } from "starknet"
3
3
 
4
4
  export enum RiskType {
5
- MARKET_RISK = 'MARKET_RISK',
6
- IMPERMANENT_LOSS = 'IMPERMANENT_LOSS',
7
- LIQUIDITY_RISK = 'LIQUIDITY_RISK',
8
- SMART_CONTRACT_RISK = 'SMART_CONTRACT_RISK',
9
- TECHNICAL_RISK = 'TECHNICAL_RISK',
10
- COUNTERPARTY_RISK = 'COUNTERPARTY_RISK', // e.g. bad debt
5
+ MARKET_RISK = 'Market Risk',
6
+ // if non-correalted pairs, this is 3 (STRK/USDC)
7
+ // if highly correalted pairs, this is 1 (e.g. xSTRK/STRK)
8
+ // if correalted pairs, this is 2 (e.g. BTC/SOL)
9
+ // If there is added leverage on top, can go till 5
10
+ IMPERMANENT_LOSS = 'Impermanent Loss Risk',
11
+ LIQUIDATION_RISK = 'Liquidation Risk',
12
+ LOW_LIQUIDITY_RISK = 'Low Liquidity Risk',
13
+ SMART_CONTRACT_RISK = 'Smart Contract Risk',
14
+ ORACLE_RISK = 'Oracle Risk',
15
+ TECHNICAL_RISK = 'Technical Risk',
16
+ COUNTERPARTY_RISK = 'Counterparty Risk', // e.g. bad debt
11
17
  }
12
18
 
13
19
  export interface RiskFactor {
@@ -19,7 +25,7 @@ export interface RiskFactor {
19
25
  export interface TokenInfo {
20
26
  name: string,
21
27
  symbol: string,
22
- address: string,
28
+ address: ContractAddr,
23
29
  decimals: number,
24
30
  logo: string,
25
31
  coingeckId?: string,
@@ -53,7 +59,7 @@ export enum FlowChartColors {
53
59
  * @property risk.riskFactor.factor - The risk factors that are considered for the strategy.
54
60
  * @property risk.riskFactor.factor - The value of the risk factor from 0 to 10, 0 being the lowest and 10 being the highest.
55
61
  */
56
- export interface IStrategyMetadata {
62
+ export interface IStrategyMetadata<T> {
57
63
  name: string,
58
64
  description: string,
59
65
  address: ContractAddr,
@@ -65,7 +71,8 @@ export interface IStrategyMetadata {
65
71
  risk: {
66
72
  riskFactor: RiskFactor[],
67
73
  netRisk: number
68
- }
74
+ },
75
+ additionalInfo: T
69
76
  }
70
77
 
71
78
  export interface IInvestmentFlow {
@@ -84,4 +91,44 @@ export function getMainnetConfig(rpcUrl = "https://starknet-mainnet.public.blast
84
91
  stage: "production",
85
92
  network: Network.mainnet
86
93
  }
94
+ }
95
+
96
+ export const getRiskExplaination = (riskType: RiskType) => {
97
+ switch (riskType) {
98
+ case RiskType.MARKET_RISK:
99
+ return "The risk of the market moving against the position."
100
+ case RiskType.IMPERMANENT_LOSS:
101
+ return "The temporary loss of value experienced by liquidity providers in AMMs when asset prices diverge compared to simply holding them."
102
+ case RiskType.LIQUIDATION_RISK:
103
+ return "The risk of losing funds due to the position being liquidated."
104
+ case RiskType.LOW_LIQUIDITY_RISK:
105
+ return "The risk of low liquidity in the pool, which can lead to high slippages or reduced in-abilities to quickly exit the position."
106
+ case RiskType.ORACLE_RISK:
107
+ return "The risk of the oracle being manipulated or incorrect."
108
+ case RiskType.SMART_CONTRACT_RISK:
109
+ return "The risk of the smart contract being vulnerable to attacks."
110
+ case RiskType.TECHNICAL_RISK:
111
+ return "The risk of technical issues e.g. backend failure."
112
+ case RiskType.COUNTERPARTY_RISK:
113
+ return "The risk of the counterparty defaulting e.g. bad debt on lending platforms."
114
+ }
115
+ }
116
+
117
+ export const getRiskColor = (risk: RiskFactor) => {
118
+ const value = risk.value;
119
+ if (value === 0) return 'green';
120
+ if (value < 2.5) return 'yellow';
121
+ return 'red';
122
+ }
123
+
124
+ export const getNoRiskTags = (risks: RiskFactor[]) => {
125
+ const noRisks1 = risks.filter(risk => risk.value === 0).map(risk => risk.type);
126
+
127
+ // const risks not present
128
+ const noRisks2 = Object.values(RiskType).filter(risk => !risks.map(risk => risk.type).includes(risk));
129
+
130
+ const mergedUnique = [...new Set([...noRisks1, ...noRisks2])];
131
+
132
+ // add `No` to the start of each risk
133
+ return mergedUnique.map(risk => `No ${risk}`);
87
134
  }
@@ -4,7 +4,7 @@ import { ContractAddr } from "@/dataTypes/address";
4
4
  import { loggers } from "winston";
5
5
  import { logger } from "@/global";
6
6
  import { log } from "console";
7
- import { Web3Number } from "@/dataTypes/bignumber";
7
+ import { Web3Number } from "@/dataTypes";
8
8
 
9
9
  export interface ILendingMetadata {
10
10
  name: string;
@@ -0,0 +1,93 @@
1
+ import { uint256 } from "starknet";
2
+
3
+ import { Call, Uint256 } from "starknet";
4
+ import { fetchBuildExecuteTransaction, fetchQuotes, Quote } from "@avnu/avnu-sdk";
5
+ import { assert } from "../utils";
6
+
7
+ export interface Route {
8
+ token_from: string,
9
+ token_to: string,
10
+ exchange_address: string,
11
+ percent: number,
12
+ additional_swap_params: string[]
13
+ }
14
+
15
+ export interface SwapInfo {
16
+ token_from_address: string,
17
+ token_from_amount: Uint256,
18
+ token_to_address: string,
19
+ token_to_amount: Uint256,
20
+ token_to_min_amount: Uint256,
21
+ beneficiary: string,
22
+ integrator_fee_amount_bps: number,
23
+ integrator_fee_recipient: string,
24
+ routes: Route[]
25
+ }
26
+
27
+
28
+ export class AvnuWrapper {
29
+ async getQuotes(
30
+ fromToken: string,
31
+ toToken: string,
32
+ amountWei: string,
33
+ taker: string,
34
+ ) {
35
+ const params: any = {
36
+ sellTokenAddress: fromToken,
37
+ buyTokenAddress: toToken,
38
+ sellAmount: amountWei,
39
+ takerAddress: taker,
40
+ };
41
+ assert(fromToken != toToken, 'From and to tokens are the same');
42
+
43
+ const quotes = await fetchQuotes(params);
44
+ assert(quotes.length > 0, 'No quotes found');
45
+ return quotes[0];
46
+ }
47
+
48
+ async getSwapInfo(
49
+ quote: Quote,
50
+ taker: string,
51
+ integratorFeeBps: number,
52
+ integratorFeeRecipient: string,
53
+ minAmount: string
54
+ ) {
55
+ const calldata = await fetchBuildExecuteTransaction(quote.quoteId);
56
+ // its the multi swap function call
57
+ const call: Call = calldata.calls[1];
58
+ const callData: string[] = call.calldata as string[];
59
+ const routesLen: number = Number(callData[11]);
60
+ assert(routesLen > 0, 'No routes found');
61
+
62
+ // use call data to re-construct routes
63
+ let startIndex = 12;
64
+ const routes: Route[] = [];
65
+ for(let i=0; i<routesLen; ++i) {
66
+ const swap_params_len = Number(callData[startIndex + 4]);
67
+ const route: Route = {
68
+ token_from: callData[startIndex],
69
+ token_to: callData[startIndex + 1],
70
+ exchange_address: callData[startIndex + 2],
71
+ percent: Number(callData[startIndex + 3]),
72
+ additional_swap_params: swap_params_len > 0 ? callData.slice(startIndex + 5, startIndex + 5 + swap_params_len): []
73
+ }
74
+ routes.push(route);
75
+ startIndex += 5 + swap_params_len;
76
+ }
77
+
78
+ // swapInfo as expected by the strategy
79
+ const swapInfo: SwapInfo = {
80
+ token_from_address: quote.sellTokenAddress,
81
+ token_from_amount: uint256.bnToUint256(quote.sellAmount),
82
+ token_to_address: quote.buyTokenAddress,
83
+ token_to_amount: uint256.bnToUint256(quote.buyAmount),
84
+ token_to_min_amount: uint256.bnToUint256(minAmount),
85
+ beneficiary: taker,
86
+ integrator_fee_amount_bps: integratorFeeBps,
87
+ integrator_fee_recipient: integratorFeeRecipient,
88
+ routes
89
+ };
90
+
91
+ return swapInfo;
92
+ }
93
+ }
@@ -0,0 +1,23 @@
1
+ import { ContractAddr, Web3Number } from "@/dataTypes";
2
+ import { IConfig } from "@/interfaces";
3
+ import { Contract } from "starknet";
4
+ import ERC20Abi from '@/data/erc20.abi.json';
5
+
6
+ export class ERC20 {
7
+ readonly config: IConfig;
8
+
9
+ constructor(config: IConfig) {
10
+ this.config = config;
11
+ }
12
+
13
+ contract(addr: string | ContractAddr) {
14
+ const _addr = typeof addr === 'string' ? addr : addr.address;
15
+ return new Contract(ERC20Abi, _addr, this.config.provider);
16
+ }
17
+
18
+ async balanceOf(token: string | ContractAddr, address: string | ContractAddr, tokenDecimals: number) {
19
+ const contract = this.contract(token);
20
+ const balance = await contract.call('balanceOf', [address.toString()]);
21
+ return Web3Number.fromWei(balance.toString(), tokenDecimals);
22
+ }
23
+ }
@@ -2,3 +2,5 @@ export * from './pricer';
2
2
  export * from './pragma';
3
3
  export * from './zkLend';
4
4
  export * from './pricer-from-api';
5
+ export * from './erc20';
6
+ export * from './avnu';
@@ -183,7 +183,7 @@ export class Pricer extends PricerBase {
183
183
  }
184
184
 
185
185
  async _getPriceEkubo(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
186
- const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address).replace("{{AMOUNT}}", amountIn.toWei());
186
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
187
187
  const result = await axios.get(url);
188
188
  const data: any = result.data;
189
189
  const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6));
@@ -1,6 +1,6 @@
1
1
  import axios from "axios";
2
2
  import BigNumber from "bignumber.js";
3
- import { Web3Number } from "@/dataTypes/bignumber";
3
+ import { Web3Number } from "@/dataTypes/bignumber.browser";
4
4
  import { FatalError, Global, logger } from "@/global";
5
5
  import { TokenInfo } from "@/interfaces";
6
6
  import { ILending, ILendingPosition, LendingToken, MarginType } from "@/interfaces/lending";
@@ -36,7 +36,7 @@ export class ZkLend extends ILending implements ILending {
36
36
  const token: LendingToken = {
37
37
  name: pool.token.name,
38
38
  symbol: pool.token.symbol,
39
- address: savedTokenInfo?.address || '',
39
+ address: savedTokenInfo?.address || ContractAddr.from(''),
40
40
  logo: '',
41
41
  decimals: pool.token.decimals,
42
42
  borrowFactor: Web3Number.fromWei(pool.borrow_factor.value, pool.borrow_factor.decimals),
@@ -0,0 +1,9 @@
1
+ import axios from 'axios';
2
+
3
+ export async function getAPIUsingHeadlessBrowser(
4
+ url: string
5
+ ) {
6
+ const res = await axios.get(url);
7
+ return res.data;
8
+ }
9
+
@@ -0,0 +1,36 @@
1
+ const puppeteer = require('puppeteer');
2
+
3
+ export async function getAPIUsingHeadlessBrowser(
4
+ url: string
5
+ ) {
6
+
7
+ try {
8
+ // Launch a headless browser
9
+ const browser = await puppeteer.launch({ headless: true });
10
+ const page = await browser.newPage();
11
+
12
+ // Set a realistic User-Agent to avoid suspicion
13
+ await page.setUserAgent(
14
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
15
+ );
16
+
17
+ // Go to the API endpoint
18
+ await page.goto(url, {
19
+ waitUntil: 'networkidle2', // Wait until the page fully loads (including JS challenge)
20
+ });
21
+
22
+ // If the API returns JSON, extract it
23
+ const jsonData = await page.evaluate(() => {
24
+ const pre = document.querySelector('pre'); // Adjust based on how the API response is formatted
25
+ return pre && pre.textContent ? JSON.parse(pre.textContent) : null;
26
+ });
27
+
28
+ // Clean up
29
+ await browser.close();
30
+ return jsonData;
31
+ } catch (error) {
32
+ console.error('Error:', error);
33
+ return null;
34
+ }
35
+ }
36
+
@@ -0,0 +1 @@
1
+ export * from './headless.browser';
package/src/node/index.ts CHANGED
@@ -1 +1,2 @@
1
- export * from './pricer-redis';
1
+ export * from './pricer-redis';
2
+ export * from '@/node/headless';
@@ -0,0 +1,47 @@
1
+ import { ContractAddr, Web3Number } from "@/dataTypes";
2
+ import { IConfig, TokenInfo } from "@/interfaces";
3
+ import { Call } from "starknet";
4
+
5
+ export interface SingleActionAmount {
6
+ tokenInfo: TokenInfo,
7
+ amount: Web3Number
8
+ }
9
+
10
+ export interface SingleTokenInfo extends SingleActionAmount {
11
+ usdValue: number
12
+ };
13
+
14
+ export interface DualActionAmount {
15
+ token0: SingleActionAmount,
16
+ token1: SingleActionAmount
17
+ }
18
+ export interface DualTokenInfo {
19
+ netUsdValue: number,
20
+ token0: SingleTokenInfo,
21
+ token1: SingleTokenInfo
22
+ }
23
+
24
+ export class BaseStrategy<TVLInfo, ActionInfo> {
25
+ readonly config: IConfig;
26
+
27
+ constructor(config: IConfig) {
28
+ this.config = config;
29
+ }
30
+
31
+ async getUserTVL(user: ContractAddr): Promise<TVLInfo> {
32
+ throw new Error("Not implemented");
33
+ }
34
+
35
+ async getTVL(): Promise<TVLInfo> {
36
+ throw new Error("Not implemented");
37
+ }
38
+
39
+ depositCall(amountInfo: ActionInfo, receiver: ContractAddr): Call[] {
40
+ throw new Error("Not implemented");
41
+ }
42
+
43
+ withdrawCall(amountInfo: ActionInfo, receiver: ContractAddr, owner: ContractAddr): Call[] {
44
+ throw new Error("Not implemented");
45
+ }
46
+
47
+ }