@defisaver/ethena-sdk 0.0.4 → 0.0.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.
Files changed (76) hide show
  1. package/cjs/config/contracts.d.ts +181 -0
  2. package/cjs/config/contracts.js +72 -0
  3. package/cjs/constants/index.d.ts +7 -0
  4. package/cjs/constants/index.js +10 -0
  5. package/cjs/contracts.d.ts +696 -0
  6. package/cjs/contracts.js +80 -0
  7. package/cjs/exchange/index.d.ts +10 -0
  8. package/cjs/exchange/index.js +185 -0
  9. package/cjs/execution/index.d.ts +2 -0
  10. package/cjs/execution/index.js +15 -0
  11. package/cjs/execution/morpho.d.ts +2 -0
  12. package/cjs/execution/morpho.js +56 -0
  13. package/cjs/index.d.ts +5 -1
  14. package/cjs/index.js +9 -1
  15. package/cjs/positionData/index.d.ts +1 -1
  16. package/cjs/positionData/index.js +2 -2
  17. package/cjs/positionData/morpho.d.ts +1 -1
  18. package/cjs/positionData/morpho.js +15 -7
  19. package/cjs/safe/index.d.ts +6 -0
  20. package/cjs/safe/index.js +80 -0
  21. package/cjs/services/viem.d.ts +31 -31
  22. package/cjs/types/common.d.ts +10 -0
  23. package/cjs/types/exchange.d.ts +19 -0
  24. package/cjs/types/exchange.js +12 -0
  25. package/cjs/types/execution.d.ts +9 -0
  26. package/cjs/types/execution.js +8 -0
  27. package/cjs/types/index.d.ts +3 -0
  28. package/cjs/types/index.js +3 -0
  29. package/cjs/types/safe.d.ts +5 -0
  30. package/cjs/types/safe.js +2 -0
  31. package/esm/config/contracts.d.ts +181 -0
  32. package/esm/config/contracts.js +69 -0
  33. package/esm/constants/index.d.ts +7 -0
  34. package/esm/constants/index.js +7 -0
  35. package/esm/contracts.d.ts +696 -0
  36. package/esm/contracts.js +37 -0
  37. package/esm/exchange/index.d.ts +10 -0
  38. package/esm/exchange/index.js +176 -0
  39. package/esm/execution/index.d.ts +2 -0
  40. package/esm/execution/index.js +11 -0
  41. package/esm/execution/morpho.d.ts +2 -0
  42. package/esm/execution/morpho.js +52 -0
  43. package/esm/index.d.ts +5 -1
  44. package/esm/index.js +5 -1
  45. package/esm/positionData/index.d.ts +1 -1
  46. package/esm/positionData/index.js +2 -2
  47. package/esm/positionData/morpho.d.ts +1 -1
  48. package/esm/positionData/morpho.js +16 -8
  49. package/esm/safe/index.d.ts +6 -0
  50. package/esm/safe/index.js +75 -0
  51. package/esm/services/viem.d.ts +31 -31
  52. package/esm/types/common.d.ts +10 -0
  53. package/esm/types/exchange.d.ts +19 -0
  54. package/esm/types/exchange.js +9 -0
  55. package/esm/types/execution.d.ts +9 -0
  56. package/esm/types/execution.js +5 -0
  57. package/esm/types/index.d.ts +3 -0
  58. package/esm/types/index.js +3 -0
  59. package/esm/types/safe.d.ts +5 -0
  60. package/esm/types/safe.js +1 -0
  61. package/package.json +3 -1
  62. package/src/config/contracts.ts +72 -0
  63. package/src/constants/index.ts +7 -0
  64. package/src/contracts.ts +57 -0
  65. package/src/exchange/index.ts +195 -0
  66. package/src/execution/index.ts +12 -0
  67. package/src/execution/morpho.ts +47 -0
  68. package/src/index.ts +8 -0
  69. package/src/positionData/index.ts +2 -2
  70. package/src/positionData/morpho.ts +17 -8
  71. package/src/safe/index.ts +99 -0
  72. package/src/types/common.ts +11 -0
  73. package/src/types/exchange.ts +21 -0
  74. package/src/types/execution.ts +11 -0
  75. package/src/types/index.ts +4 -1
  76. package/src/types/safe.ts +5 -0
@@ -0,0 +1,80 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getSafeFallbackHandlerAddress = exports.getSafeFactoryAddress = exports.getSafeWalletSingletonAddress = exports.getSafeWalletContract = exports.MorphoManagerContract = exports.SafeFactoryContract = exports.Safe130Contract = exports.createContractFromConfigFunc = exports.getConfigContractAbi = exports.getConfigContractAddress = void 0;
37
+ const viem_1 = require("viem");
38
+ const positions_sdk_1 = require("@defisaver/positions-sdk");
39
+ const configRaw = __importStar(require("./config/contracts"));
40
+ // @ts-ignore
41
+ const contractConfig = configRaw;
42
+ const getConfigContractAddress = (name, network) => {
43
+ const networkData = contractConfig[name].networks[network];
44
+ const latestAddress = (networkData === null || networkData === void 0 ? void 0 : networkData.address) || '';
45
+ return latestAddress;
46
+ };
47
+ exports.getConfigContractAddress = getConfigContractAddress;
48
+ const getConfigContractAbi = (name) => {
49
+ const latestAbi = contractConfig[name].abi;
50
+ return latestAbi;
51
+ };
52
+ exports.getConfigContractAbi = getConfigContractAbi;
53
+ const createContractFromConfigFunc = (name, _address) => (client, network) => {
54
+ const address = (_address || (0, exports.getConfigContractAddress)(name, network));
55
+ const abi = (0, exports.getConfigContractAbi)(name);
56
+ return (0, viem_1.getContract)({
57
+ address,
58
+ abi,
59
+ client,
60
+ });
61
+ };
62
+ exports.createContractFromConfigFunc = createContractFromConfigFunc;
63
+ exports.Safe130Contract = (0, exports.createContractFromConfigFunc)('Safe130');
64
+ exports.SafeFactoryContract = (0, exports.createContractFromConfigFunc)('SafeProxyFactory130');
65
+ exports.MorphoManagerContract = (0, exports.createContractFromConfigFunc)('MorphoManager');
66
+ const getSafeWalletContract = (client, address) => {
67
+ const abi = (0, exports.getConfigContractAbi)('Safe130');
68
+ return (0, viem_1.getContract)({
69
+ address,
70
+ abi,
71
+ client,
72
+ });
73
+ };
74
+ exports.getSafeWalletContract = getSafeWalletContract;
75
+ const getSafeWalletSingletonAddress = (network) => (0, exports.getConfigContractAddress)('Safe130', network || positions_sdk_1.NetworkNumber.Eth);
76
+ exports.getSafeWalletSingletonAddress = getSafeWalletSingletonAddress;
77
+ const getSafeFactoryAddress = (network) => (0, exports.getConfigContractAddress)('SafeProxyFactory130', network || positions_sdk_1.NetworkNumber.Eth);
78
+ exports.getSafeFactoryAddress = getSafeFactoryAddress;
79
+ const getSafeFallbackHandlerAddress = (network) => (0, exports.getConfigContractAddress)('SafeFallbackHandler130', network || positions_sdk_1.NetworkNumber.Eth);
80
+ exports.getSafeFallbackHandlerAddress = getSafeFallbackHandlerAddress;
@@ -0,0 +1,10 @@
1
+ import { NetworkNumber } from '@defisaver/positions-sdk';
2
+ import { OffchainExchanges, PriceData } from '../types';
3
+ export declare const numStringToBytes: (num: number) => string;
4
+ export declare const getBestPrice: (fromAsset: string, toAsset: string, amount: string, userAddress: string, network?: NetworkNumber) => Promise<PriceData>;
5
+ export declare const getExchangeOrder: (fromAsset: string, toAsset: string, amount: string, userAddress: string, minPrice: string, network?: NetworkNumber) => Promise<{
6
+ orderData: (string | string[])[];
7
+ value: string;
8
+ source: OffchainExchanges | "None";
9
+ price: string;
10
+ }>;
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getExchangeOrder = exports.getBestPrice = exports.numStringToBytes = void 0;
16
+ const decimal_js_1 = __importDefault(require("decimal.js"));
17
+ const bn_js_1 = __importDefault(require("bn.js"));
18
+ const positions_sdk_1 = require("@defisaver/positions-sdk");
19
+ const tokens_1 = require("@defisaver/tokens");
20
+ const types_1 = require("../types");
21
+ const constants_1 = require("../constants");
22
+ const getOffchainEmptyData = (source = 'None') => ({
23
+ wrapper: constants_1.ZERO_ADDRESS,
24
+ to: constants_1.ZERO_ADDRESS,
25
+ allowanceTarget: constants_1.ZERO_ADDRESS,
26
+ price: '0',
27
+ priceWithFee: '0',
28
+ protocolFee: '0',
29
+ data: '0x00',
30
+ value: '0',
31
+ gas: '0',
32
+ source,
33
+ });
34
+ const parsePriceWithDecimals = (price, fromDecimals, toDecimals) => new decimal_js_1.default(price)
35
+ .div(Math.pow(10, toDecimals))
36
+ .div(Math.pow(10, (18 - fromDecimals)))
37
+ .toString();
38
+ const formatPriceWithDecimalForContract = (price, fromDecimals, toDecimals) => new decimal_js_1.default(price)
39
+ .mul(Math.pow(10, toDecimals))
40
+ .mul(Math.pow(10, (18 - fromDecimals)))
41
+ .floor()
42
+ .toString();
43
+ const includeFeeInPrice = (price, from, to, fee) => {
44
+ if (from === to)
45
+ return price;
46
+ return new decimal_js_1.default(price).mul(new decimal_js_1.default(1).sub(fee)).toString();
47
+ };
48
+ const excludeFeeFromPrice = (price, from, to, fee) => {
49
+ if (from === to)
50
+ return price;
51
+ return new decimal_js_1.default(price).mul(new decimal_js_1.default(1).add(fee)).toString();
52
+ };
53
+ const parseOffchainPrice = (fromTokenSymbol, fromTokenDecimals, toTokenSymbol, toTokenDecimals, amount, feeDecimal) => {
54
+ const _price = parsePriceWithDecimals(amount, fromTokenDecimals, toTokenDecimals);
55
+ return includeFeeInPrice(_price, fromTokenSymbol, toTokenSymbol, feeDecimal);
56
+ };
57
+ const getFeeDecimal = () => new decimal_js_1.default(1).div(constants_1.STABLE_PAIR_FEE_DIVIDER).toString();
58
+ const numStringToBytes = (num) => {
59
+ const bn = new bn_js_1.default(num.toString()).toTwos(256);
60
+ return bn.toString(16);
61
+ };
62
+ exports.numStringToBytes = numStringToBytes;
63
+ const getPriceFromServer = (fromAsset_1, toAsset_1, amount_1, userAddress_1, ...args_1) => __awaiter(void 0, [fromAsset_1, toAsset_1, amount_1, userAddress_1, ...args_1], void 0, function* (fromAsset, toAsset, amount, userAddress, network = positions_sdk_1.NetworkNumber.Eth, infoOnly = true) {
64
+ const fromAssetData = (0, tokens_1.getAssetInfo)(fromAsset, network);
65
+ const toAssetData = (0, tokens_1.getAssetInfo)(toAsset, network);
66
+ const feeDecimal = getFeeDecimal();
67
+ const excludedSources = ['Balancer_V2', 'Beethovenx'];
68
+ const allSources = Object.values(types_1.OffchainExchanges);
69
+ try {
70
+ const res = yield fetch(`${constants_1.DFS_API_URL}/api/exchange/get-best-price`, {
71
+ method: 'POST',
72
+ headers: {
73
+ 'Content-Type': 'application/json',
74
+ },
75
+ body: JSON.stringify({
76
+ fromAsset: fromAssetData.address,
77
+ fromAssetDecimals: fromAssetData.decimals,
78
+ fromAssetSymbol: fromAssetData.symbol,
79
+ toAsset: toAssetData.address,
80
+ toAssetDecimals: toAssetData.decimals,
81
+ toAssetSymbol: toAssetData.symbol,
82
+ sources: [...allSources.map(s => s.toLowerCase())],
83
+ chainId: network,
84
+ amount,
85
+ excludedSources,
86
+ infoOnly,
87
+ takerAddress: userAddress,
88
+ account: userAddress,
89
+ noFee: false,
90
+ feeDecimal,
91
+ // temporary fix for paraswap until old exchange service is removed
92
+ shouldFormatParaswapPrice: true,
93
+ }),
94
+ });
95
+ if (!res.ok)
96
+ throw new Error(yield res.text());
97
+ const data = (yield res.json());
98
+ const formattedData = data.map((d, i) => {
99
+ const source = allSources[i];
100
+ if (typeof d === 'string')
101
+ return getOffchainEmptyData(source);
102
+ return {
103
+ wrapper: d.wrapper || constants_1.ZERO_ADDRESS,
104
+ to: d.to || constants_1.ZERO_ADDRESS,
105
+ allowanceTarget: d.allowanceTarget || constants_1.ZERO_ADDRESS,
106
+ protocolFee: d.protocolFee || '0',
107
+ data: d.data || '0x00',
108
+ value: d.value || '0',
109
+ gas: d.gas || '0',
110
+ source: allSources[i],
111
+ price: d.price,
112
+ priceWithFee: +(d.price || '0') > 0
113
+ ? parseOffchainPrice(fromAssetData.symbol, fromAssetData.decimals, toAssetData.symbol, toAssetData.decimals, d.price, feeDecimal)
114
+ : '0',
115
+ };
116
+ }).filter((d) => d.wrapper !== constants_1.ZERO_ADDRESS && d.price !== '0').sort((a, b) => (new decimal_js_1.default(a.price).gt(b.price) ? -1 : 1));
117
+ return formattedData;
118
+ }
119
+ catch (_a) {
120
+ return allSources.map(source => getOffchainEmptyData(source));
121
+ }
122
+ });
123
+ const getBestPrice = (fromAsset_1, toAsset_1, amount_1, userAddress_1, ...args_1) => __awaiter(void 0, [fromAsset_1, toAsset_1, amount_1, userAddress_1, ...args_1], void 0, function* (fromAsset, toAsset, amount, userAddress, network = positions_sdk_1.NetworkNumber.Eth) {
124
+ try {
125
+ const formattedData = yield getPriceFromServer(fromAsset, toAsset, amount, userAddress, network);
126
+ return formattedData[0] || getOffchainEmptyData();
127
+ }
128
+ catch (e) {
129
+ console.error('Error fetching best price:', e);
130
+ return getOffchainEmptyData();
131
+ }
132
+ });
133
+ exports.getBestPrice = getBestPrice;
134
+ const getExchangeOrder = (fromAsset_1, toAsset_1, amount_1, userAddress_1, minPrice_1, ...args_1) => __awaiter(void 0, [fromAsset_1, toAsset_1, amount_1, userAddress_1, minPrice_1, ...args_1], void 0, function* (fromAsset, toAsset, amount, userAddress, minPrice, network = positions_sdk_1.NetworkNumber.Eth) {
135
+ const fromAssetData = (0, tokens_1.getAssetInfo)(fromAsset, network);
136
+ const toAssetData = (0, tokens_1.getAssetInfo)(toAsset, network);
137
+ const feeDecimal = getFeeDecimal();
138
+ const offchainQuotes = yield getPriceFromServer(fromAsset, toAsset, amount, userAddress, network, false);
139
+ const formattedOffchainQuotes = offchainQuotes.map((quote) => ({
140
+ source: quote.source,
141
+ price: quote.priceWithFee,
142
+ wrapper: quote.wrapper,
143
+ wrapperData: quote.data,
144
+ offchainData: quote,
145
+ }));
146
+ const bestQuote = formattedOffchainQuotes[0];
147
+ const { offchainData, source, price } = bestQuote;
148
+ const minPriceFormatted = new decimal_js_1.default(excludeFeeFromPrice(minPrice, fromAssetData.address, toAssetData.address, feeDecimal))
149
+ .mul(100 - constants_1.SLIPPAGE_PERCENT)
150
+ .div(100)
151
+ .toString();
152
+ const minPriceForContract = formatPriceWithDecimalForContract(minPriceFormatted, fromAssetData.decimals, toAssetData.decimals);
153
+ const offchainDataArray = [
154
+ offchainData.wrapper,
155
+ offchainData.to,
156
+ offchainData.allowanceTarget,
157
+ offchainData.price,
158
+ offchainData.protocolFee,
159
+ offchainData.data,
160
+ ];
161
+ const value = offchainData.protocolFee;
162
+ const wrapper = constants_1.ZERO_ADDRESS;
163
+ const wrapperData = `0x${(0, exports.numStringToBytes)(Math.floor(Date.now() / 1000))}`;
164
+ const amountWei = (0, tokens_1.assetAmountInWei)(amount, fromAsset).toString();
165
+ if (offchainData.data === '0x00')
166
+ throw new Error('Offchain data is empty');
167
+ return {
168
+ orderData: [
169
+ fromAssetData.address,
170
+ toAssetData.address,
171
+ amountWei,
172
+ '0',
173
+ minPriceForContract,
174
+ constants_1.STABLE_PAIR_FEE_DIVIDER,
175
+ '0x0000000000000000000000000000000000000000', // set by contract
176
+ wrapper,
177
+ wrapperData,
178
+ offchainDataArray,
179
+ ],
180
+ value,
181
+ source,
182
+ price,
183
+ };
184
+ });
185
+ exports.getExchangeOrder = getExchangeOrder;
@@ -0,0 +1,2 @@
1
+ import { SupportedMarkets } from '../types';
2
+ export declare const getRequests: (market: SupportedMarkets) => import("../types").Request[];
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRequests = void 0;
4
+ const types_1 = require("../types");
5
+ const morpho_1 = require("./morpho");
6
+ const getRequests = (market) => {
7
+ switch (market) {
8
+ case types_1.SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
9
+ return (0, morpho_1.getMorphoRequests)();
10
+ }
11
+ default:
12
+ throw new Error(`Unsupported market: ${market}`);
13
+ }
14
+ };
15
+ exports.getRequests = getRequests;
@@ -0,0 +1,2 @@
1
+ import { Request } from '../types';
2
+ export declare const getMorphoRequests: () => Request[];
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getMorphoRequests = void 0;
13
+ const contracts_1 = require("../contracts");
14
+ const viem_1 = require("../services/viem");
15
+ const types_1 = require("../types");
16
+ const safe_1 = require("../safe");
17
+ const morphoAuthSignature = {
18
+ type: types_1.RequestType.Signature,
19
+ getParams: (rpcUrl, network, userAddress) => __awaiter(void 0, void 0, void 0, function* () {
20
+ const provider = (0, viem_1.getViemProvider)(rpcUrl, network);
21
+ const managerContract = (0, contracts_1.MorphoManagerContract)(provider, network);
22
+ const nonce = yield managerContract.read.nonce([userAddress]);
23
+ const tenMinutes = 1000 * 60 * 10;
24
+ const deadline = Date.now() + tenMinutes;
25
+ const safeAddress = yield (0, safe_1.predictSafeAddress)(userAddress, rpcUrl, network);
26
+ return {
27
+ types: {
28
+ EIP712Domain: [
29
+ { name: 'verifyingContract', type: 'address' },
30
+ { name: 'chainId', type: 'uint256' },
31
+ ],
32
+ Authorization: [
33
+ { name: 'authorizer', type: 'address' },
34
+ { name: 'authorized', type: 'address' },
35
+ { name: 'isAuthorized', type: 'bool' },
36
+ { name: 'nonce', type: 'uint256' },
37
+ { name: 'deadline', type: 'uint256' },
38
+ ],
39
+ },
40
+ domain: {
41
+ chainId: network,
42
+ verifyingContract: managerContract.address,
43
+ },
44
+ primaryType: 'Authorization',
45
+ message: {
46
+ authorizer: userAddress,
47
+ authorized: safeAddress,
48
+ isAuthorized: true,
49
+ nonce: +nonce.toString(),
50
+ deadline,
51
+ },
52
+ };
53
+ }),
54
+ };
55
+ const getMorphoRequests = () => [morphoAuthSignature];
56
+ exports.getMorphoRequests = getMorphoRequests;
package/cjs/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import './setup';
2
2
  import * as positionData from './positionData';
3
3
  import * as marketData from './marketData';
4
+ import * as exchange from './exchange';
5
+ import * as constants from './constants';
6
+ import * as safe from './safe';
7
+ import * as execution from './execution';
4
8
  export * from './types';
5
- export { positionData, marketData, };
9
+ export { positionData, marketData, exchange, constants, safe, execution, };
package/cjs/index.js CHANGED
@@ -36,10 +36,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
36
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.marketData = exports.positionData = void 0;
39
+ exports.execution = exports.safe = exports.constants = exports.exchange = exports.marketData = exports.positionData = void 0;
40
40
  require("./setup");
41
41
  const positionData = __importStar(require("./positionData"));
42
42
  exports.positionData = positionData;
43
43
  const marketData = __importStar(require("./marketData"));
44
44
  exports.marketData = marketData;
45
+ const exchange = __importStar(require("./exchange"));
46
+ exports.exchange = exchange;
47
+ const constants = __importStar(require("./constants"));
48
+ exports.constants = constants;
49
+ const safe = __importStar(require("./safe"));
50
+ exports.safe = safe;
51
+ const execution = __importStar(require("./execution"));
52
+ exports.execution = execution;
45
53
  __exportStar(require("./types"), exports);
@@ -1,3 +1,3 @@
1
1
  import { MarketData, NetworkNumber, PositionData } from '../types';
2
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>;
3
+ export declare const getResultingPosition: (marketData: MarketData, supplyAmount: string, leverage: number, userAddress: string, rpcUrl: string, network: NetworkNumber) => Promise<PositionData>;
@@ -22,10 +22,10 @@ const getMaxLeverageForSupplyAmount = (marketData, supplyAmount) => {
22
22
  }
23
23
  };
24
24
  exports.getMaxLeverageForSupplyAmount = getMaxLeverageForSupplyAmount;
25
- const getResultingPosition = (marketData, supplyAmount, leverage, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
25
+ const getResultingPosition = (marketData, supplyAmount, leverage, userAddress, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
26
26
  switch (marketData.market) {
27
27
  case types_1.SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
28
- return (0, morpho_1.getMorphoResultingPosition)(marketData, supplyAmount, leverage, rpcUrl, network);
28
+ return (0, morpho_1.getMorphoResultingPosition)(marketData, supplyAmount, leverage, userAddress, rpcUrl, network);
29
29
  }
30
30
  default:
31
31
  throw new Error(`Unsupported market: ${marketData.market}`);
@@ -1,4 +1,4 @@
1
1
  import { NetworkNumber } from '@defisaver/positions-sdk';
2
2
  import { MarketData, PositionData } from '../types';
3
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>;
4
+ export declare const getMorphoResultingPosition: (marketData: MarketData, supplyAmount: string, leverage: number, userAddress: string, rpcUrl: string, network: NetworkNumber) => Promise<PositionData>;
@@ -17,6 +17,7 @@ const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const tokens_1 = require("@defisaver/tokens");
18
18
  const positions_sdk_1 = require("@defisaver/positions-sdk");
19
19
  const viem_1 = require("../services/viem");
20
+ const exchange_1 = require("../exchange");
20
21
  const getMaxBoostUsd = (lltv, borrowLimit, debt, targetRatio = 1.01, bufferPercent = 1) => new decimal_js_1.default(targetRatio).mul(debt).sub(borrowLimit)
21
22
  .div(new decimal_js_1.default(lltv).sub(targetRatio).toString())
22
23
  .mul((100 - bufferPercent) / 100)
@@ -37,19 +38,19 @@ const getMorphoMaxLeverageForSupplyAmount = (marketData, supplyAmount) => {
37
38
  return maxLeverage;
38
39
  };
39
40
  exports.getMorphoMaxLeverageForSupplyAmount = getMorphoMaxLeverageForSupplyAmount;
40
- const getMorphoResultingPosition = (marketData, supplyAmount, leverage, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
41
+ const getMorphoResultingPosition = (marketData, supplyAmount, leverage, userAddress, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
41
42
  const provider = (0, viem_1.getViemProvider)(rpcUrl, network);
42
43
  const morphoMarket = positions_sdk_1.markets.MorphoBlueMarkets(network)[positions_sdk_1.MorphoBlueVersions.MorphoBlueSUSDeUSDtb_915];
43
44
  const { rate: oracle, assetsData, } = marketData;
45
+ const supplyAsset = Object.values(assetsData).find((asset) => !asset.isDebtAsset);
46
+ const borrowAsset = Object.values(assetsData).find((asset) => asset.isDebtAsset);
44
47
  const debtAmount = new decimal_js_1.default(leverage)
45
48
  .times(supplyAmount).minus(supplyAmount).times(oracle)
46
49
  .toString();
47
- // TODO: add price fetching logic
48
- const priceForAmount = new decimal_js_1.default(1).div(oracle).toString();
49
- const leveragedAmount = new decimal_js_1.default(debtAmount).times(priceForAmount);
50
+ const debtAmountWei = (0, tokens_1.assetAmountInWei)(debtAmount, borrowAsset.symbol);
51
+ const { priceWithFee, source } = yield (0, exchange_1.getBestPrice)(borrowAsset.symbol, supplyAsset.symbol, debtAmountWei, userAddress, network);
52
+ const leveragedAmount = new decimal_js_1.default(debtAmount).times(priceWithFee);
50
53
  const collIncrease = new decimal_js_1.default(supplyAmount).plus(leveragedAmount).toString();
51
- const supplyAsset = Object.values(assetsData).find((asset) => !asset.isDebtAsset);
52
- const borrowAsset = Object.values(assetsData).find((asset) => asset.isDebtAsset);
53
54
  const morphoMarketData = yield positions_sdk_1.morphoBlue._getMorphoBlueMarketData(provider, network, morphoMarket);
54
55
  const usedAssets = {};
55
56
  usedAssets[borrowAsset.symbol] = {
@@ -73,6 +74,13 @@ const getMorphoResultingPosition = (marketData, supplyAmount, leverage, rpcUrl,
73
74
  borrowedUsd: '0',
74
75
  };
75
76
  const aggregatedPosition = positions_sdk_1.helpers.morphoBlueHelpers.getMorphoBlueAggregatedPositionData({ usedAssets, assetsData: morphoMarketData.assetsData, marketInfo: morphoMarketData });
76
- return Object.assign({ usedAssets }, aggregatedPosition);
77
+ return Object.assign({ exchangeInfo: {
78
+ price: priceWithFee,
79
+ source,
80
+ sellAsset: borrowAsset.symbol,
81
+ sellAmount: debtAmount,
82
+ buyAsset: supplyAsset.symbol,
83
+ buyAmount: leveragedAmount.toString(),
84
+ }, usedAssets }, aggregatedPosition);
77
85
  });
78
86
  exports.getMorphoResultingPosition = getMorphoResultingPosition;
@@ -0,0 +1,6 @@
1
+ import { NetworkNumber } from '@defisaver/positions-sdk';
2
+ export declare const getSafeWallets: (userAddress: string, network: NetworkNumber) => Promise<{
3
+ success: boolean;
4
+ wallets: string[];
5
+ }>;
6
+ export declare const predictSafeAddress: (owner: string, rpcUrl: string, network: NetworkNumber) => Promise<string>;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.predictSafeAddress = exports.getSafeWallets = void 0;
13
+ const viem_1 = require("viem");
14
+ const constants_1 = require("../constants");
15
+ const contracts_1 = require("../contracts");
16
+ const viem_2 = require("../services/viem");
17
+ const getSafeWallets = (userAddress, network) => __awaiter(void 0, void 0, void 0, function* () {
18
+ try {
19
+ const res = yield fetch(`${constants_1.SAFE_API_URL}/safe/all-wallets?network=${network}&account=${userAddress}`);
20
+ const wallets = yield res.json();
21
+ const oneOneWallets = wallets
22
+ .filter((wallet) => wallet.type === 'Safe' && (wallet.owners || []).length === 1)
23
+ .map((wallet) => wallet.address);
24
+ return { success: true, wallets: oneOneWallets };
25
+ }
26
+ catch (e) {
27
+ return { success: false, wallets: [] };
28
+ }
29
+ });
30
+ exports.getSafeWallets = getSafeWallets;
31
+ const getSafeSetupParams = (owners, threshold, network) => [
32
+ owners,
33
+ BigInt(threshold),
34
+ constants_1.ZERO_ADDRESS,
35
+ '0x',
36
+ (0, contracts_1.getSafeFallbackHandlerAddress)(network),
37
+ constants_1.ZERO_ADDRESS,
38
+ BigInt(0),
39
+ constants_1.SAFE_REFUND_RECEIVER,
40
+ ];
41
+ const _predictSafeAddress = (rpcUrl, network, setupArgs, saltNonce) => __awaiter(void 0, void 0, void 0, function* () {
42
+ const provider = (0, viem_2.getViemProvider)(rpcUrl, network);
43
+ const safeProxyFactoryAddress = (0, contracts_1.getSafeFactoryAddress)(network);
44
+ const safeProxyFactoryContract = (0, contracts_1.SafeFactoryContract)(provider, network);
45
+ const masterCopyAddress = (0, contracts_1.getSafeWalletSingletonAddress)(network);
46
+ const proxyCreationCode = yield safeProxyFactoryContract.read.proxyCreationCode();
47
+ // @ts-ignore
48
+ const initCodeHash = (0, viem_1.keccak256)((0, viem_1.encodePacked)(['bytes', 'bytes'], [proxyCreationCode, masterCopyAddress.slice(2).padStart(64, '0')]), 'bytes');
49
+ const salt = (0, viem_1.keccak256)((0, viem_1.encodePacked)(['bytes', 'uint256'], [(0, viem_1.keccak256)(setupArgs), BigInt(saltNonce)]));
50
+ return (0, viem_1.getCreate2Address)({
51
+ bytecodeHash: initCodeHash,
52
+ from: safeProxyFactoryAddress,
53
+ salt,
54
+ });
55
+ });
56
+ const predictSafeAddress = (owner, rpcUrl, network) => __awaiter(void 0, void 0, void 0, function* () {
57
+ const provider = (0, viem_2.getViemProvider)(rpcUrl, network);
58
+ const threshold = 1;
59
+ const owners = [owner];
60
+ const setupParams = getSafeSetupParams(owners, threshold, network);
61
+ const setupParamsEncoded = (0, viem_1.encodeFunctionData)({
62
+ abi: (0, contracts_1.getConfigContractAbi)('Safe130'),
63
+ functionName: 'setup',
64
+ // @ts-ignore
65
+ args: setupParams,
66
+ });
67
+ const oneOfOneWalletsCount = (yield (0, exports.getSafeWallets)(owner, network)).wallets.length;
68
+ const failAfter = 10;
69
+ for (let nonce = oneOfOneWalletsCount + 1; nonce < oneOfOneWalletsCount + failAfter + 1; nonce += 1) {
70
+ const salt = `${constants_1.SALT_PREFIX}${nonce}`;
71
+ const predictedAddr = yield _predictSafeAddress(rpcUrl, network, setupParamsEncoded, salt);
72
+ const bytecode = yield provider.getCode({ address: predictedAddr });
73
+ if (!bytecode) {
74
+ // safe does not exist
75
+ return predictedAddr;
76
+ }
77
+ }
78
+ return '';
79
+ });
80
+ exports.predictSafeAddress = predictSafeAddress;