@defisaver/ethena-sdk 0.0.2 → 0.0.4

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.
Files changed (47) hide show
  1. package/cjs/index.d.ts +5 -0
  2. package/cjs/index.js +45 -0
  3. package/cjs/marketData/index.d.ts +4 -0
  4. package/cjs/marketData/index.js +34 -0
  5. package/cjs/marketData/morpho.d.ts +4 -0
  6. package/cjs/marketData/morpho.js +76 -0
  7. package/cjs/positionData/index.d.ts +3 -0
  8. package/cjs/positionData/index.js +34 -0
  9. package/cjs/positionData/morpho.d.ts +4 -0
  10. package/cjs/positionData/morpho.js +78 -0
  11. package/cjs/services/viem.d.ts +4404 -0
  12. package/cjs/services/viem.js +27 -0
  13. package/cjs/setup.d.ts +1 -0
  14. package/cjs/setup.js +12 -0
  15. package/cjs/types/common.d.ts +24 -0
  16. package/cjs/types/common.js +5 -0
  17. package/cjs/types/index.d.ts +2 -0
  18. package/cjs/types/index.js +18 -0
  19. package/cjs/types/markets.d.ts +3 -0
  20. package/cjs/types/markets.js +7 -0
  21. package/esm/index.d.ts +5 -0
  22. package/esm/index.js +5 -0
  23. package/esm/marketData/index.d.ts +4 -0
  24. package/esm/marketData/index.js +29 -0
  25. package/esm/marketData/morpho.d.ts +4 -0
  26. package/esm/marketData/morpho.js +68 -0
  27. package/esm/positionData/index.d.ts +3 -0
  28. package/esm/positionData/index.js +29 -0
  29. package/esm/positionData/morpho.d.ts +4 -0
  30. package/esm/positionData/morpho.js +70 -0
  31. package/esm/services/viem.d.ts +4394 -0
  32. package/esm/services/viem.js +22 -0
  33. package/esm/setup.d.ts +1 -0
  34. package/esm/setup.js +7 -0
  35. package/esm/types/common.d.ts +24 -0
  36. package/esm/types/common.js +2 -0
  37. package/esm/types/index.d.ts +2 -0
  38. package/esm/types/index.js +2 -0
  39. package/esm/types/markets.d.ts +3 -0
  40. package/esm/types/markets.js +4 -0
  41. package/package.json +1 -5
  42. package/.env.example +0 -1
  43. package/.eslintrc.js +0 -34
  44. package/tests/morpho.ts +0 -51
  45. package/tsconfig.cjs.json +0 -7
  46. package/tsconfig.esm.json +0 -11
  47. package/tsconfig.json +0 -25
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getViemProvider = exports.getViemChain = void 0;
4
+ const positions_sdk_1 = require("@defisaver/positions-sdk");
5
+ const viem_1 = require("viem");
6
+ const chains_1 = require("viem/chains");
7
+ const getViemChain = (network) => {
8
+ switch (network) {
9
+ case positions_sdk_1.NetworkNumber.Eth:
10
+ return chains_1.mainnet;
11
+ case positions_sdk_1.NetworkNumber.Opt:
12
+ return chains_1.optimism;
13
+ case positions_sdk_1.NetworkNumber.Arb:
14
+ return chains_1.arbitrum;
15
+ case positions_sdk_1.NetworkNumber.Base:
16
+ return chains_1.base;
17
+ case positions_sdk_1.NetworkNumber.Linea:
18
+ return chains_1.linea;
19
+ case positions_sdk_1.NetworkNumber.Plasma:
20
+ return chains_1.plasma;
21
+ default:
22
+ throw new Error(`Unsupported network: ${network}`);
23
+ }
24
+ };
25
+ exports.getViemChain = getViemChain;
26
+ const getViemProvider = (rpcUrl, network, options) => (0, viem_1.createPublicClient)(Object.assign({ transport: (0, viem_1.http)(rpcUrl), chain: (0, exports.getViemChain)(network) }, options));
27
+ exports.getViemProvider = getViemProvider;
package/cjs/setup.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/cjs/setup.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const decimal_js_1 = __importDefault(require("decimal.js"));
7
+ decimal_js_1.default.set({
8
+ rounding: decimal_js_1.default.ROUND_DOWN,
9
+ toExpPos: 9e15,
10
+ toExpNeg: -9e15,
11
+ precision: 50,
12
+ });
@@ -0,0 +1,24 @@
1
+ import { IncentiveData, MMUsedAssets, MorphoBlueAggregatedPositionData, NetworkNumber } from '@defisaver/positions-sdk';
2
+ import { SupportedMarkets } from './markets';
3
+ export interface AssetData {
4
+ symbol: string;
5
+ address: string;
6
+ supplyRate: string;
7
+ borrowRate: string;
8
+ supplyIncentives: IncentiveData[];
9
+ borrowIncentives: IncentiveData[];
10
+ isDebtAsset: boolean;
11
+ }
12
+ export interface MarketData {
13
+ market: SupportedMarkets;
14
+ maxLeverage: number;
15
+ assetsData: Record<string, AssetData>;
16
+ maxApy: string;
17
+ leftToBorrowGlobal: string;
18
+ lltv: string;
19
+ rate: string;
20
+ }
21
+ export interface PositionData extends MorphoBlueAggregatedPositionData {
22
+ usedAssets: MMUsedAssets;
23
+ }
24
+ export { NetworkNumber, MMUsedAssets, IncentiveData, };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkNumber = void 0;
4
+ const positions_sdk_1 = require("@defisaver/positions-sdk");
5
+ Object.defineProperty(exports, "NetworkNumber", { enumerable: true, get: function () { return positions_sdk_1.NetworkNumber; } });
@@ -0,0 +1,2 @@
1
+ export * from './common';
2
+ export * from './markets';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./common"), exports);
18
+ __exportStar(require("./markets"), exports);
@@ -0,0 +1,3 @@
1
+ export declare enum SupportedMarkets {
2
+ MorphoBlueSUSDeUSDtb_915 = "morphobluesusdeusdtb_915"
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SupportedMarkets = void 0;
4
+ var SupportedMarkets;
5
+ (function (SupportedMarkets) {
6
+ SupportedMarkets["MorphoBlueSUSDeUSDtb_915"] = "morphobluesusdeusdtb_915";
7
+ })(SupportedMarkets || (exports.SupportedMarkets = SupportedMarkets = {}));
package/esm/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import './setup';
2
+ import * as positionData from './positionData';
3
+ import * as marketData from './marketData';
4
+ export * from './types';
5
+ export { positionData, marketData, };
package/esm/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import './setup';
2
+ import * as positionData from './positionData';
3
+ import * as marketData from './marketData';
4
+ export * from './types';
5
+ export { positionData, marketData, };
@@ -0,0 +1,4 @@
1
+ import { NetworkNumber } from '@defisaver/positions-sdk';
2
+ import { MarketData, SupportedMarkets } from '../types';
3
+ export declare const getMarketData: (market: SupportedMarkets, rpcUrl: string, network: NetworkNumber) => Promise<MarketData>;
4
+ export declare const getNetApy: (marketData: MarketData, leverage: number) => string;
@@ -0,0 +1,29 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { SupportedMarkets } from '../types';
11
+ import { getMorphoMarketData, getMorphoNetApy, } from './morpho';
12
+ export const getMarketData = (market, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
13
+ switch (market) {
14
+ case SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
15
+ return getMorphoMarketData(market, rpcUrl, network);
16
+ }
17
+ default:
18
+ throw new Error(`Unsupported market: ${market}`);
19
+ }
20
+ });
21
+ export const getNetApy = (marketData, leverage) => {
22
+ switch (marketData.market) {
23
+ case SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
24
+ return getMorphoNetApy(marketData, leverage);
25
+ }
26
+ default:
27
+ throw new Error(`Unsupported market: ${marketData.market}`);
28
+ }
29
+ };
@@ -0,0 +1,4 @@
1
+ import { NetworkNumber } from '@defisaver/positions-sdk';
2
+ import { MarketData, SupportedMarkets } from '../types';
3
+ export declare const getMorphoMarketData: (market: SupportedMarkets, rpcUrl: string, network: NetworkNumber) => Promise<MarketData>;
4
+ export declare const getMorphoNetApy: (marketData: MarketData, leverage: number) => string;
@@ -0,0 +1,68 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { helpers, markets, morphoBlue, MorphoBlueVersions, } from '@defisaver/positions-sdk';
11
+ import Dec from 'decimal.js';
12
+ import { assetAmountInEth } from '@defisaver/tokens';
13
+ import { getViemProvider } from '../services/viem';
14
+ const getMaxLeverage = (collateralFactor) => new Dec(1)
15
+ .div(new Dec(1).sub(collateralFactor))
16
+ .toDP(2).toString();
17
+ const scaleMaxLeverage = (leverage) => leverage * 0.9;
18
+ const getLevApy = (leverage, supplyAsset, borrowAsset) => {
19
+ const supplyRate = new Dec(supplyAsset.supplyRate).add(supplyAsset.supplyIncentives.reduce((acc, curr) => acc.add(curr.apy), new Dec(0)));
20
+ const borrowRate = new Dec(borrowAsset.borrowRate).add(borrowAsset.borrowIncentives.reduce((acc, curr) => acc.add(curr.apy), new Dec(0)));
21
+ return new Dec(leverage).mul(supplyRate)
22
+ .sub(new Dec(leverage).sub(1).mul(borrowRate))
23
+ .toDP(4)
24
+ .toString();
25
+ };
26
+ const formatAssetsData = (assetsData) => {
27
+ const formattedData = {};
28
+ Object.entries(assetsData).forEach(([assetSymbol, assetData]) => {
29
+ formattedData[assetSymbol] = {
30
+ symbol: assetData.symbol,
31
+ address: assetData.address,
32
+ supplyRate: assetData.supplyRate,
33
+ borrowRate: assetData.borrowRate,
34
+ supplyIncentives: assetData.supplyIncentives,
35
+ borrowIncentives: assetData.borrowIncentives,
36
+ isDebtAsset: assetData.canBeBorrowed,
37
+ };
38
+ });
39
+ return formattedData;
40
+ };
41
+ export const getMorphoMarketData = (market, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
42
+ const provider = getViemProvider(rpcUrl, network);
43
+ const morphoMarket = markets.MorphoBlueMarkets(network)[MorphoBlueVersions.MorphoBlueSUSDeUSDtb_915];
44
+ const [marketData, { reallocatableLiquidity: availableLiquidityWei }] = yield Promise.all([
45
+ morphoBlue._getMorphoBlueMarketData(provider, network, morphoMarket),
46
+ helpers.morphoBlueHelpers.getReallocatableLiquidity(morphoMarket.marketId, network),
47
+ ]);
48
+ const maxLeverageFactor = getMaxLeverage(marketData.lltv);
49
+ const scaledMaxLeverage = scaleMaxLeverage(parseFloat(maxLeverageFactor));
50
+ const assetsData = formatAssetsData(marketData.assetsData);
51
+ const availableLiquidity = assetAmountInEth(availableLiquidityWei, 'USDtb');
52
+ const leftToBorrowGlobal = new Dec(marketData.assetsData.USDtb.totalSupply || '0').sub(marketData.assetsData.USDtb.totalBorrow || '0').toString();
53
+ const leftToBorrowGlobalAdjusted = new Dec(availableLiquidity).add(leftToBorrowGlobal).toString();
54
+ return {
55
+ market,
56
+ maxLeverage: scaledMaxLeverage,
57
+ assetsData,
58
+ maxApy: getLevApy(scaledMaxLeverage, assetsData.sUSDe, assetsData.USDtb),
59
+ leftToBorrowGlobal: leftToBorrowGlobalAdjusted,
60
+ lltv: marketData.lltv,
61
+ rate: marketData.oracle,
62
+ };
63
+ });
64
+ export const getMorphoNetApy = (marketData, leverage) => {
65
+ const supplyAsset = Object.values(marketData.assetsData).find((asset) => !asset.isDebtAsset);
66
+ const borrowAsset = Object.values(marketData.assetsData).find((asset) => asset.isDebtAsset);
67
+ return getLevApy(leverage, supplyAsset, borrowAsset);
68
+ };
@@ -0,0 +1,3 @@
1
+ import { MarketData, NetworkNumber, PositionData } from '../types';
2
+ export declare const getMaxLeverageForSupplyAmount: (marketData: MarketData, supplyAmount: string) => number;
3
+ export declare const getResultingPosition: (marketData: MarketData, supplyAmount: string, leverage: number, rpcUrl: string, network: NetworkNumber) => Promise<PositionData>;
@@ -0,0 +1,29 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { SupportedMarkets, } from '../types';
11
+ import { getMorphoMaxLeverageForSupplyAmount, getMorphoResultingPosition } from './morpho';
12
+ export const getMaxLeverageForSupplyAmount = (marketData, supplyAmount) => {
13
+ switch (marketData.market) {
14
+ case SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
15
+ return getMorphoMaxLeverageForSupplyAmount(marketData, supplyAmount);
16
+ }
17
+ default:
18
+ throw new Error(`Unsupported market: ${marketData.market}`);
19
+ }
20
+ };
21
+ export const getResultingPosition = (marketData, supplyAmount, leverage, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
22
+ switch (marketData.market) {
23
+ case SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
24
+ return getMorphoResultingPosition(marketData, supplyAmount, leverage, rpcUrl, network);
25
+ }
26
+ default:
27
+ throw new Error(`Unsupported market: ${marketData.market}`);
28
+ }
29
+ });
@@ -0,0 +1,4 @@
1
+ import { NetworkNumber } from '@defisaver/positions-sdk';
2
+ import { MarketData, PositionData } from '../types';
3
+ export declare const getMorphoMaxLeverageForSupplyAmount: (marketData: MarketData, supplyAmount: string) => number;
4
+ export declare const getMorphoResultingPosition: (marketData: MarketData, supplyAmount: string, leverage: number, rpcUrl: string, network: NetworkNumber) => Promise<PositionData>;
@@ -0,0 +1,70 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import Dec from 'decimal.js';
11
+ import { getAssetInfo } from '@defisaver/tokens';
12
+ import { helpers, markets, morphoBlue, MorphoBlueVersions, } from '@defisaver/positions-sdk';
13
+ import { getViemProvider } from '../services/viem';
14
+ const getMaxBoostUsd = (lltv, borrowLimit, debt, targetRatio = 1.01, bufferPercent = 1) => new Dec(targetRatio).mul(debt).sub(borrowLimit)
15
+ .div(new Dec(lltv).sub(targetRatio).toString())
16
+ .mul((100 - bufferPercent) / 100)
17
+ .toString();
18
+ const getMorphoMaxLeverageBorrow = (marketData, supplyAmount) => {
19
+ const { lltv, rate: oracle, assetsData, leftToBorrowGlobal, } = marketData;
20
+ const borrowAsset = Object.values(assetsData).find((asset) => asset.isDebtAsset);
21
+ const maxBorrow = new Dec(supplyAmount).mul(oracle).mul(lltv).toString();
22
+ const maxBoost = getMaxBoostUsd(lltv, maxBorrow, '0');
23
+ return Dec.min(Dec.max(0, maxBoost), leftToBorrowGlobal).toDP(getAssetInfo(borrowAsset === null || borrowAsset === void 0 ? void 0 : borrowAsset.symbol).decimals).toString();
24
+ };
25
+ export const getMorphoMaxLeverageForSupplyAmount = (marketData, supplyAmount) => {
26
+ // TODO: implement FL logic
27
+ const feeMultiplier = 1;
28
+ const maxDebt = new Dec(getMorphoMaxLeverageBorrow(marketData, supplyAmount)).div(feeMultiplier).toString();
29
+ const rate = new Dec(1).div(marketData.rate).toString();
30
+ const maxLeverage = new Dec(supplyAmount).plus(new Dec(maxDebt).times(rate)).div(supplyAmount).toNumber();
31
+ return maxLeverage;
32
+ };
33
+ export const getMorphoResultingPosition = (marketData, supplyAmount, leverage, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
34
+ const provider = getViemProvider(rpcUrl, network);
35
+ const morphoMarket = markets.MorphoBlueMarkets(network)[MorphoBlueVersions.MorphoBlueSUSDeUSDtb_915];
36
+ const { rate: oracle, assetsData, } = marketData;
37
+ const debtAmount = new Dec(leverage)
38
+ .times(supplyAmount).minus(supplyAmount).times(oracle)
39
+ .toString();
40
+ // TODO: add price fetching logic
41
+ const priceForAmount = new Dec(1).div(oracle).toString();
42
+ const leveragedAmount = new Dec(debtAmount).times(priceForAmount);
43
+ const collIncrease = new Dec(supplyAmount).plus(leveragedAmount).toString();
44
+ const supplyAsset = Object.values(assetsData).find((asset) => !asset.isDebtAsset);
45
+ const borrowAsset = Object.values(assetsData).find((asset) => asset.isDebtAsset);
46
+ const morphoMarketData = yield morphoBlue._getMorphoBlueMarketData(provider, network, morphoMarket);
47
+ const usedAssets = {};
48
+ usedAssets[borrowAsset.symbol] = {
49
+ symbol: borrowAsset.symbol,
50
+ supplied: '0',
51
+ borrowed: debtAmount,
52
+ isSupplied: false,
53
+ isBorrowed: true,
54
+ collateral: false,
55
+ suppliedUsd: '0',
56
+ borrowedUsd: new Dec(debtAmount).mul(morphoMarketData.assetsData[borrowAsset.symbol].price).toString(),
57
+ };
58
+ usedAssets[supplyAsset.symbol] = {
59
+ symbol: supplyAsset.symbol,
60
+ supplied: collIncrease,
61
+ borrowed: '0',
62
+ isSupplied: true,
63
+ isBorrowed: false,
64
+ collateral: true,
65
+ suppliedUsd: new Dec(collIncrease).mul(morphoMarketData.assetsData[supplyAsset.symbol].price).toString(),
66
+ borrowedUsd: '0',
67
+ };
68
+ const aggregatedPosition = helpers.morphoBlueHelpers.getMorphoBlueAggregatedPositionData({ usedAssets, assetsData: morphoMarketData.assetsData, marketInfo: morphoMarketData });
69
+ return Object.assign({ usedAssets }, aggregatedPosition);
70
+ });