@evaafi/sdk 0.5.5 → 0.5.6-a

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 (42) hide show
  1. package/dist/api/math.d.ts +22 -3
  2. package/dist/api/math.js +141 -50
  3. package/dist/api/parser.d.ts +3 -3
  4. package/dist/api/parser.js +32 -15
  5. package/dist/config.d.ts +1 -0
  6. package/dist/config.js +4 -0
  7. package/dist/constants/assets.d.ts +2 -3
  8. package/dist/constants/assets.js +10 -2
  9. package/dist/constants/general.d.ts +3 -2
  10. package/dist/constants/general.js +6 -5
  11. package/dist/constants/pools.d.ts +0 -1
  12. package/dist/constants/pools.js +1 -14
  13. package/dist/constants.d.ts +4 -4
  14. package/dist/constants.js +15 -7
  15. package/dist/contracts/MasterContract.d.ts +13 -45
  16. package/dist/contracts/MasterContract.js +8 -10
  17. package/dist/contracts/UserContract.js +7 -7
  18. package/dist/index.d.ts +4 -3
  19. package/dist/index.js +3 -2
  20. package/dist/types/Master.d.ts +8 -7
  21. package/dist/types/User.d.ts +5 -5
  22. package/dist/utils/merkleProof.d.ts +4 -0
  23. package/dist/utils/merkleProof.js +108 -0
  24. package/dist/utils/priceUtils.d.ts +55 -0
  25. package/dist/utils/priceUtils.js +117 -0
  26. package/dist/utils/userJettonWallet.d.ts +2 -2
  27. package/dist/utils/userJettonWallet.js +4 -0
  28. package/dist/utils/utils.d.ts +2 -0
  29. package/dist/utils/utils.js +7 -0
  30. package/package.json +2 -3
  31. package/src/api/math.ts +169 -51
  32. package/src/api/parser.ts +50 -25
  33. package/src/constants/assets.ts +11 -3
  34. package/src/constants/general.ts +6 -4
  35. package/src/constants/pools.ts +1 -15
  36. package/src/contracts/MasterContract.ts +23 -65
  37. package/src/contracts/UserContract.ts +8 -10
  38. package/src/index.ts +2 -6
  39. package/src/types/Master.ts +9 -8
  40. package/src/types/User.ts +5 -5
  41. package/src/utils/userJettonWallet.ts +6 -2
  42. package/src/utils/utils.ts +6 -0
@@ -1,7 +1,7 @@
1
1
  import { Address, Cell, Contract, ContractProvider, OpenedContract, Sender } from '@ton/core';
2
2
  import { Maybe } from '@ton/core/dist/utils/maybe';
3
3
  import { EvaaUser } from './UserContract';
4
- import { MasterData, PoolAssetConfig, PoolConfig, PoolJettonAssetConfig } from '../types/Master';
4
+ import { MasterData, PoolAssetConfig, PoolConfig } from '../types/Master';
5
5
  /**
6
6
  * Parameters for the Evaa contract
7
7
  * @property testnet - true for testnet, false for mainnet
@@ -11,44 +11,23 @@ export type EvaaParameters = {
11
11
  poolConfig: PoolConfig;
12
12
  debug?: boolean;
13
13
  };
14
- /**
15
- * Parameters for the Jetton message
16
- * @property responseAddress - address to send excesses
17
- * @property forwardAmount - amount to forward to the destination address
18
- */
19
- export type JettonMessageParameters = {
20
- responseAddress?: Address;
21
- forwardAmount?: bigint;
22
- };
23
14
  /**
24
15
  * Base parameters for supply
25
16
  * @property queryID - unique query ID
26
17
  * @property includeUserCode - true to include user code for update (needed when user contract code version is outdated)
27
18
  * @property amount - amount to supply
28
19
  * @property userAddress - user address
29
- * @property assetID - asset ID
20
+ * @property asset
30
21
  */
31
- export type SupplyBaseParameters = {
22
+ export type SupplyParameters = {
23
+ asset: PoolAssetConfig;
32
24
  queryID: bigint;
33
25
  includeUserCode: boolean;
34
26
  amount: bigint;
35
27
  userAddress: Address;
28
+ responseAddress?: Address;
29
+ forwardAmount?: bigint;
36
30
  };
37
- /**
38
- * Parameters for the TON supply message
39
- * @property type - 'ton'
40
- */
41
- export type TonSupplyParameters = SupplyBaseParameters & {
42
- asset: PoolAssetConfig;
43
- };
44
- /**
45
- * Parameters for the jetton supply message
46
- * @property type - 'jetton'
47
- */
48
- export type JettonSupplyParameters = SupplyBaseParameters & JettonMessageParameters & {
49
- asset: PoolJettonAssetConfig & PoolAssetConfig;
50
- };
51
- export type SupplyParameters = TonSupplyParameters | JettonSupplyParameters;
52
31
  /**
53
32
  * Parameters for the withdraw message
54
33
  * @property queryID - unique query ID
@@ -91,25 +70,14 @@ export type LiquidationBaseData = {
91
70
  * @property includeUserCode - true to include user code for update (needed when user contract code version is outdated)
92
71
  * @property priceData - price data cell. Can be obtained from the getPrices function
93
72
  */
94
- export type LiquidationBaseParameters = LiquidationBaseData & {
73
+ export type LiquidationParameters = LiquidationBaseData & {
74
+ asset: PoolAssetConfig;
95
75
  queryID: bigint;
96
76
  liquidatorAddress: Address;
97
77
  includeUserCode: boolean;
98
78
  priceData: Cell;
99
- };
100
- /**
101
- * Parameters for the TON liquidation message
102
- * @property type - 'ton'
103
- */
104
- export type TonLiquidationParameters = LiquidationBaseParameters & {
105
- asset: PoolAssetConfig;
106
- };
107
- /**
108
- * Parameters for the jetton liquidation message
109
- * @property type - 'jetton'
110
- */
111
- export type JettonLiquidationParameters = LiquidationBaseParameters & JettonMessageParameters & {
112
- asset: PoolAssetConfig & PoolJettonAssetConfig;
79
+ responseAddress?: Address;
80
+ forwardAmount?: bigint;
113
81
  };
114
82
  /**
115
83
  * Evaa master contract wrapper
@@ -139,7 +107,7 @@ export declare class Evaa implements Contract {
139
107
  * Create liquidation message
140
108
  * @returns liquidation message as a cell
141
109
  */
142
- createLiquidationMessage(parameters: TonLiquidationParameters | JettonLiquidationParameters): Cell;
110
+ createLiquidationMessage(parameters: LiquidationParameters): Cell;
143
111
  /**
144
112
  * Calculate user contract address
145
113
  * @param userAddress
@@ -157,9 +125,9 @@ export declare class Evaa implements Contract {
157
125
  * Get master contract data
158
126
  */
159
127
  get data(): Maybe<MasterData>;
160
- sendSupply(provider: ContractProvider, via: Sender, value: bigint, parameters: TonSupplyParameters | JettonSupplyParameters): Promise<void>;
128
+ sendSupply(provider: ContractProvider, via: Sender, value: bigint, parameters: SupplyParameters): Promise<void>;
161
129
  sendWithdraw(provider: ContractProvider, via: Sender, value: bigint, parameters: WithdrawParameters): Promise<void>;
162
- sendLiquidation(provider: ContractProvider, via: Sender, value: bigint, parameters: TonLiquidationParameters | JettonLiquidationParameters): Promise<void>;
130
+ sendLiquidation(provider: ContractProvider, via: Sender, value: bigint, parameters: LiquidationParameters): Promise<void>;
163
131
  /**
164
132
  * Open user contract wrapper
165
133
  * @param forwardPayload - payload that will be forwarded to the address which requested the data
@@ -27,16 +27,15 @@ class Evaa {
27
27
  * @returns supply message as a cell
28
28
  */
29
29
  createSupplyMessage(parameters) {
30
- if ('jettonMasterAddress' in parameters.asset) {
31
- const jettonParams = parameters;
30
+ if (!(0, __1.isTonAsset)(parameters.asset)) {
32
31
  return (0, core_1.beginCell)()
33
32
  .storeUint(general_1.OPCODES.JETTON_TRANSFER, 32)
34
33
  .storeUint(parameters.queryID, 64)
35
34
  .storeCoins(parameters.amount)
36
35
  .storeAddress(this.address)
37
- .storeAddress(jettonParams.responseAddress ?? parameters.userAddress)
36
+ .storeAddress(parameters.responseAddress ?? parameters.userAddress)
38
37
  .storeBit(0)
39
- .storeCoins(jettonParams.forwardAmount ?? general_1.FEES.SUPPLY_JETTON_FWD)
38
+ .storeCoins(parameters.forwardAmount ?? general_1.FEES.SUPPLY_JETTON_FWD)
40
39
  .storeBit(1)
41
40
  .storeRef((0, core_1.beginCell)()
42
41
  .storeUint(general_1.OPCODES.SUPPLY, 32)
@@ -84,16 +83,15 @@ class Evaa {
84
83
  * @returns liquidation message as a cell
85
84
  */
86
85
  createLiquidationMessage(parameters) {
87
- if ('jettonMasterAddress' in parameters.asset) {
88
- const jettonParams = parameters;
86
+ if (!(0, __1.isTonAsset)(parameters.asset)) {
89
87
  return (0, core_1.beginCell)()
90
88
  .storeUint(general_1.OPCODES.JETTON_TRANSFER, 32)
91
89
  .storeUint(parameters.queryID, 64)
92
90
  .storeCoins(parameters.liquidationAmount)
93
91
  .storeAddress(this.address)
94
- .storeAddress(jettonParams.responseAddress ?? parameters.liquidatorAddress)
92
+ .storeAddress(parameters.responseAddress ?? parameters.liquidatorAddress)
95
93
  .storeBit(0)
96
- .storeCoins(jettonParams.forwardAmount ?? general_1.FEES.LIQUIDATION_JETTON_FWD)
94
+ .storeCoins(parameters.forwardAmount ?? general_1.FEES.LIQUIDATION_JETTON_FWD)
97
95
  .storeBit(1)
98
96
  .storeRef((0, core_1.beginCell)()
99
97
  .storeUint(general_1.OPCODES.LIQUIDATE, 32)
@@ -162,7 +160,7 @@ class Evaa {
162
160
  }
163
161
  async sendSupply(provider, via, value, parameters) {
164
162
  const message = this.createSupplyMessage(parameters);
165
- if ('jettonMasterAddress' in parameters.asset) {
163
+ if (!(0, __1.isTonAsset)(parameters.asset)) {
166
164
  if (!via.address) {
167
165
  throw Error('Via address is required for jetton supply');
168
166
  }
@@ -187,7 +185,7 @@ class Evaa {
187
185
  }
188
186
  async sendLiquidation(provider, via, value, parameters) {
189
187
  const message = this.createLiquidationMessage(parameters);
190
- if ('jettonMasterAddress' in parameters.asset) {
188
+ if (!(0, __1.isTonAsset)(parameters.asset)) {
191
189
  if (!via.address) {
192
190
  throw Error('Via address is required for jetton liquidation');
193
191
  }
@@ -25,7 +25,7 @@ class EvaaUser {
25
25
  async getSyncLite(provider, assetsData, assetsConfig) {
26
26
  const state = (await provider.getState()).state;
27
27
  if (state.type === 'active') {
28
- this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig.poolAssetsConfig, this.poolConfig.masterConstants);
28
+ this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig);
29
29
  this.lastSync = Math.floor(Date.now() / 1000);
30
30
  }
31
31
  else {
@@ -42,7 +42,7 @@ class EvaaUser {
42
42
  */
43
43
  calculateUserData(assetsData, assetsConfig, prices) {
44
44
  if (this._liteData) {
45
- this._data = (0, parser_1.parseUserData)(this._liteData, assetsData, assetsConfig, prices, this.poolConfig.poolAssetsConfig, this.poolConfig.masterConstants);
45
+ this._data = (0, parser_1.parseUserData)(this._liteData, assetsData, assetsConfig, prices, this.poolConfig);
46
46
  return true;
47
47
  }
48
48
  return false;
@@ -65,8 +65,8 @@ class EvaaUser {
65
65
  async getSync(provider, assetsData, assetsConfig, prices) {
66
66
  const state = (await provider.getState()).state;
67
67
  if (state.type === 'active') {
68
- this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig.poolAssetsConfig, this.poolConfig.masterConstants);
69
- this._data = (0, parser_1.parseUserData)(this._liteData, assetsData, assetsConfig, prices, this.poolConfig.poolAssetsConfig, this.poolConfig.masterConstants);
68
+ this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig);
69
+ this._data = (0, parser_1.parseUserData)(this._liteData, assetsData, assetsConfig, prices, this.poolConfig);
70
70
  this.lastSync = Math.floor(Date.now() / 1000);
71
71
  }
72
72
  else {
@@ -107,11 +107,11 @@ class EvaaUser {
107
107
  }
108
108
  return {
109
109
  borrowerAddress: this._data.ownerAddress,
110
- loanAsset: this._data.liquidationData.greatestLoanAsset,
111
- collateralAsset: this._data.liquidationData.greatestCollateralAsset,
110
+ loanAsset: this._data.liquidationData.greatestLoanAsset.assetId,
111
+ collateralAsset: this._data.liquidationData.greatestCollateralAsset.assetId,
112
112
  minCollateralAmount: this._data.liquidationData.minCollateralAmount,
113
113
  liquidationAmount: this._data.liquidationData.liquidationAmount,
114
- tonLiquidation: this._data.liquidationData.greatestLoanAsset === assets_1.TON_MAINNET.assetId,
114
+ tonLiquidation: this._data.liquidationData.greatestLoanAsset.assetId === assets_1.TON_MAINNET.assetId,
115
115
  };
116
116
  }
117
117
  }
package/dist/index.d.ts CHANGED
@@ -2,14 +2,15 @@ export { mulFactor, mulDiv, bigIntMin, bigIntMax, calculatePresentValue, calcula
2
2
  export { createAssetData, createAssetConfig, parseMasterData, parseUserData, parseUserLiteData } from './api/parser';
3
3
  export { getPrices } from './api/prices';
4
4
  export { JettonWallet } from './contracts/JettonWallet';
5
- export { EvaaParameters, JettonMessageParameters, TonSupplyParameters, JettonSupplyParameters, WithdrawParameters, LiquidationBaseData, TonLiquidationParameters, JettonLiquidationParameters, Evaa, } from './contracts/MasterContract';
5
+ export { EvaaParameters, WithdrawParameters, LiquidationBaseData, Evaa, } from './contracts/MasterContract';
6
6
  export { EvaaUser } from './contracts/UserContract';
7
7
  export { PriceData } from './types/Common';
8
8
  export { UpgradeConfig, AssetConfig, MasterConfig, AssetData, AssetInterest, AssetApy, ExtendedAssetData, MasterData, PoolConfig, ExtendedAssetsData, ExtendedAssetsConfig, PoolAssetConfig, PoolAssetsConfig, } from './types/Master';
9
9
  export { BalanceType, UserBalance, UserLiqudationData, LiquidableData, NonLiquidableData, LiquidationData, UserDataInactive, UserDataActive, UserData, BalanceChangeType } from './types/User';
10
10
  export { EVAA_MASTER_MAINNET, MAINNET_VERSION, EVAA_MASTER_TESTNET, TESTNET_VERSION, LENDING_CODE, OPCODES, FEES, MASTER_CONSTANTS } from './constants/general';
11
- export { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG, MAINNET_LP_POOL_CONFIG, TESTNET_LP_POOL_CONFIG } from './constants/pools';
12
- export { TON_MAINNET, USDT_MAINNET, TONUSDT_DEDUST_MAINNET, TON_STORM_MAINNET, USDT_STORM_MAINNET, JUSDT_MAINNET, JUSDC_MAINNET, STTON_MAINNET, TSTON_MAINNET, JUSDT_TESTNET, JUSDC_TESTNET, STTON_TESTNET, } from './constants/assets';
11
+ export { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG, MAINNET_LP_POOL_CONFIG, } from './constants/pools';
12
+ export { UNDEFINED_ASSET, TON_MAINNET, USDT_MAINNET, TONUSDT_DEDUST_MAINNET, TON_STORM_MAINNET, USDT_STORM_MAINNET, JUSDT_MAINNET, JUSDC_MAINNET, STTON_MAINNET, TSTON_MAINNET, JUSDT_TESTNET, JUSDC_TESTNET, STTON_TESTNET, } from './constants/assets';
13
13
  export * from './constants/assets';
14
+ export * from './utils/utils';
14
15
  export { getLastSentBoc, getTonConnectSender } from './utils/tonConnectSender';
15
16
  export { getUserJettonWallet } from './utils/userJettonWallet';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getUserJettonWallet = exports.getTonConnectSender = exports.getLastSentBoc = exports.STTON_TESTNET = exports.JUSDC_TESTNET = exports.JUSDT_TESTNET = exports.TSTON_MAINNET = exports.STTON_MAINNET = exports.JUSDC_MAINNET = exports.JUSDT_MAINNET = exports.USDT_STORM_MAINNET = exports.TON_STORM_MAINNET = exports.TONUSDT_DEDUST_MAINNET = exports.USDT_MAINNET = exports.TON_MAINNET = exports.TESTNET_LP_POOL_CONFIG = exports.MAINNET_LP_POOL_CONFIG = exports.TESTNET_POOL_CONFIG = exports.MAINNET_POOL_CONFIG = exports.MASTER_CONSTANTS = exports.FEES = exports.OPCODES = exports.LENDING_CODE = exports.TESTNET_VERSION = exports.EVAA_MASTER_TESTNET = exports.MAINNET_VERSION = exports.EVAA_MASTER_MAINNET = exports.BalanceChangeType = exports.BalanceType = exports.EvaaUser = exports.Evaa = exports.JettonWallet = exports.getPrices = exports.parseUserLiteData = exports.parseUserData = exports.parseMasterData = exports.createAssetConfig = exports.createAssetData = exports.calculateLiquidationData = exports.presentValue = exports.calculateMaximumWithdrawAmount = exports.getAvailableToBorrow = exports.calculateAssetInterest = exports.calculateAssetData = exports.calculateCurrentRates = exports.calculatePresentValue = exports.bigIntMax = exports.bigIntMin = exports.mulDiv = exports.mulFactor = void 0;
17
+ exports.getUserJettonWallet = exports.getTonConnectSender = exports.getLastSentBoc = exports.STTON_TESTNET = exports.JUSDC_TESTNET = exports.JUSDT_TESTNET = exports.TSTON_MAINNET = exports.STTON_MAINNET = exports.JUSDC_MAINNET = exports.JUSDT_MAINNET = exports.USDT_STORM_MAINNET = exports.TON_STORM_MAINNET = exports.TONUSDT_DEDUST_MAINNET = exports.USDT_MAINNET = exports.TON_MAINNET = exports.UNDEFINED_ASSET = exports.MAINNET_LP_POOL_CONFIG = exports.TESTNET_POOL_CONFIG = exports.MAINNET_POOL_CONFIG = exports.MASTER_CONSTANTS = exports.FEES = exports.OPCODES = exports.LENDING_CODE = exports.TESTNET_VERSION = exports.EVAA_MASTER_TESTNET = exports.MAINNET_VERSION = exports.EVAA_MASTER_MAINNET = exports.BalanceChangeType = exports.BalanceType = exports.EvaaUser = exports.Evaa = exports.JettonWallet = exports.getPrices = exports.parseUserLiteData = exports.parseUserData = exports.parseMasterData = exports.createAssetConfig = exports.createAssetData = exports.calculateLiquidationData = exports.presentValue = exports.calculateMaximumWithdrawAmount = exports.getAvailableToBorrow = exports.calculateAssetInterest = exports.calculateAssetData = exports.calculateCurrentRates = exports.calculatePresentValue = exports.bigIntMax = exports.bigIntMin = exports.mulDiv = exports.mulFactor = void 0;
18
18
  // Math
19
19
  var math_1 = require("./api/math");
20
20
  Object.defineProperty(exports, "mulFactor", { enumerable: true, get: function () { return math_1.mulFactor; } });
@@ -63,8 +63,8 @@ var pools_1 = require("./constants/pools");
63
63
  Object.defineProperty(exports, "MAINNET_POOL_CONFIG", { enumerable: true, get: function () { return pools_1.MAINNET_POOL_CONFIG; } });
64
64
  Object.defineProperty(exports, "TESTNET_POOL_CONFIG", { enumerable: true, get: function () { return pools_1.TESTNET_POOL_CONFIG; } });
65
65
  Object.defineProperty(exports, "MAINNET_LP_POOL_CONFIG", { enumerable: true, get: function () { return pools_1.MAINNET_LP_POOL_CONFIG; } });
66
- Object.defineProperty(exports, "TESTNET_LP_POOL_CONFIG", { enumerable: true, get: function () { return pools_1.TESTNET_LP_POOL_CONFIG; } });
67
66
  var assets_1 = require("./constants/assets");
67
+ Object.defineProperty(exports, "UNDEFINED_ASSET", { enumerable: true, get: function () { return assets_1.UNDEFINED_ASSET; } });
68
68
  Object.defineProperty(exports, "TON_MAINNET", { enumerable: true, get: function () { return assets_1.TON_MAINNET; } });
69
69
  Object.defineProperty(exports, "USDT_MAINNET", { enumerable: true, get: function () { return assets_1.USDT_MAINNET; } });
70
70
  Object.defineProperty(exports, "TONUSDT_DEDUST_MAINNET", { enumerable: true, get: function () { return assets_1.TONUSDT_DEDUST_MAINNET; } });
@@ -78,6 +78,7 @@ Object.defineProperty(exports, "JUSDT_TESTNET", { enumerable: true, get: functio
78
78
  Object.defineProperty(exports, "JUSDC_TESTNET", { enumerable: true, get: function () { return assets_1.JUSDC_TESTNET; } });
79
79
  Object.defineProperty(exports, "STTON_TESTNET", { enumerable: true, get: function () { return assets_1.STTON_TESTNET; } });
80
80
  __exportStar(require("./constants/assets"), exports);
81
+ __exportStar(require("./utils/utils"), exports);
81
82
  // Utils
82
83
  var tonConnectSender_1 = require("./utils/tonConnectSender");
83
84
  Object.defineProperty(exports, "getLastSentBoc", { enumerable: true, get: function () { return tonConnectSender_1.getLastSentBoc; } });
@@ -5,16 +5,13 @@ export type MasterConstants = {
5
5
  ASSET_PRICE_SCALE: bigint;
6
6
  ASSET_RESERVE_FACTOR_SCALE: bigint;
7
7
  ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: bigint;
8
+ ASSET_LIQUIDATION_THRESHOLD_SCALE: bigint;
9
+ ASSET_LIQUIDATION_BONUS_SCALE: bigint;
8
10
  ASSET_ORIGINATION_FEE_SCALE: bigint;
9
11
  };
10
- export type PoolAssetConfig = (PoolTonAssetConfig | PoolJettonAssetConfig) & {
11
- name: string;
12
- };
13
12
  export type PoolAssetsConfig = PoolAssetConfig[];
14
- export type PoolTonAssetConfig = {
15
- assetId: bigint;
16
- };
17
- export type PoolJettonAssetConfig = {
13
+ export type PoolAssetConfig = {
14
+ name: string;
18
15
  assetId: bigint;
19
16
  jettonMasterAddress: Address;
20
17
  jettonWalletCode: Cell;
@@ -94,3 +91,7 @@ export type MasterData = {
94
91
  borrow: Dictionary<bigint, number>;
95
92
  };
96
93
  };
94
+ export type AgregatedBalances = {
95
+ totalBorrow: bigint;
96
+ totalSupply: bigint;
97
+ };
@@ -1,5 +1,5 @@
1
1
  import { Address, Cell, Dictionary } from '@ton/core';
2
- import { ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants } from './Master';
2
+ import { ExtendedAssetsConfig, ExtendedAssetsData, PoolAssetConfig, PoolConfig } from './Master';
3
3
  export declare enum BalanceType {
4
4
  supply = "supply",
5
5
  borrow = "borrow"
@@ -10,9 +10,9 @@ export type UserBalance = {
10
10
  };
11
11
  export type UserLiqudationData = {
12
12
  greatestCollateralValue: bigint;
13
- greatestCollateralAsset: bigint;
13
+ greatestCollateralAsset: PoolAssetConfig;
14
14
  greatestLoanValue: bigint;
15
- greatestLoanAsset: bigint;
15
+ greatestLoanAsset: PoolAssetConfig;
16
16
  totalDebt: bigint;
17
17
  totalLimit: bigint;
18
18
  };
@@ -68,9 +68,9 @@ export type PredictHealthFactorArgs = {
68
68
  balanceChangeType: BalanceChangeType;
69
69
  amount: bigint;
70
70
  tokenSymbol: string;
71
- balances: Dictionary<bigint, bigint>;
71
+ principals: Dictionary<bigint, bigint>;
72
72
  prices: Dictionary<bigint, bigint>;
73
73
  assetsData: ExtendedAssetsData;
74
74
  assetsConfig: ExtendedAssetsConfig;
75
- masterConstants: MasterConstants;
75
+ poolConfig: PoolConfig;
76
76
  };
@@ -0,0 +1,4 @@
1
+ import { Cell, Dictionary, DictionaryKey, DictionaryKeyTypes } from "@ton/core";
2
+ export declare function convertToMerkleProof(c: Cell): Cell;
3
+ export declare function generateMerkleProofDirect<K extends DictionaryKeyTypes, V>(dict: Dictionary<K, V>, keys: K[], keyObject: DictionaryKey<K>): Cell;
4
+ export declare function generateMerkleProof<K extends DictionaryKeyTypes, V>(dict: Dictionary<K, V>, keys: K[], keyObject: DictionaryKey<K>): Cell;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMerkleProof = exports.generateMerkleProofDirect = exports.convertToMerkleProof = void 0;
4
+ const core_1 = require("@ton/core");
5
+ function readUnaryLength(slice) {
6
+ let res = 0;
7
+ while (slice.loadBit()) {
8
+ res++;
9
+ }
10
+ return res;
11
+ }
12
+ function endExoticCell(b) {
13
+ let c = b.endCell();
14
+ return new core_1.Cell({ exotic: true, bits: c.bits, refs: c.refs });
15
+ }
16
+ function convertToMerkleProof(c) {
17
+ return endExoticCell((0, core_1.beginCell)()
18
+ .storeUint(3, 8)
19
+ .storeBuffer(c.hash(0))
20
+ .storeUint(c.depth(0), 16)
21
+ .storeRef(c));
22
+ }
23
+ exports.convertToMerkleProof = convertToMerkleProof;
24
+ function convertToPrunedBranch(c) {
25
+ return endExoticCell((0, core_1.beginCell)()
26
+ .storeUint(1, 8)
27
+ .storeUint(1, 8)
28
+ .storeBuffer(c.hash(0))
29
+ .storeUint(c.depth(0), 16));
30
+ }
31
+ function doGenerateMerkleProof(prefix, slice, n, keys) {
32
+ // Reading label
33
+ const originalCell = slice.asCell();
34
+ if (keys.length == 0) {
35
+ // no keys to prove, prune the whole subdict
36
+ return convertToPrunedBranch(originalCell);
37
+ }
38
+ let lb0 = slice.loadBit() ? 1 : 0;
39
+ let prefixLength = 0;
40
+ let pp = prefix;
41
+ if (lb0 === 0) {
42
+ // Short label detected
43
+ // Read
44
+ prefixLength = readUnaryLength(slice);
45
+ // Read prefix
46
+ for (let i = 0; i < prefixLength; i++) {
47
+ pp += slice.loadBit() ? '1' : '0';
48
+ }
49
+ }
50
+ else {
51
+ let lb1 = slice.loadBit() ? 1 : 0;
52
+ if (lb1 === 0) {
53
+ // Long label detected
54
+ prefixLength = slice.loadUint(Math.ceil(Math.log2(n + 1)));
55
+ for (let i = 0; i < prefixLength; i++) {
56
+ pp += slice.loadBit() ? '1' : '0';
57
+ }
58
+ }
59
+ else {
60
+ // Same label detected
61
+ let bit = slice.loadBit() ? '1' : '0';
62
+ prefixLength = slice.loadUint(Math.ceil(Math.log2(n + 1)));
63
+ for (let i = 0; i < prefixLength; i++) {
64
+ pp += bit;
65
+ }
66
+ }
67
+ }
68
+ if (n - prefixLength === 0) {
69
+ return originalCell;
70
+ }
71
+ else {
72
+ let sl = originalCell.beginParse();
73
+ let left = sl.loadRef();
74
+ let right = sl.loadRef();
75
+ // NOTE: Left and right branches are implicitly contain prefixes '0' and '1'
76
+ if (!left.isExotic) {
77
+ const leftKeys = keys.filter((key) => {
78
+ return pp + '0' === key.slice(0, pp.length + 1);
79
+ });
80
+ left = doGenerateMerkleProof(pp + '0', left.beginParse(), n - prefixLength - 1, leftKeys);
81
+ }
82
+ if (!right.isExotic) {
83
+ const rightKeys = keys.filter((key) => {
84
+ return pp + '1' === key.slice(0, pp.length + 1);
85
+ });
86
+ right = doGenerateMerkleProof(pp + '1', right.beginParse(), n - prefixLength - 1, rightKeys);
87
+ }
88
+ return (0, core_1.beginCell)()
89
+ .storeSlice(sl)
90
+ .storeRef(left)
91
+ .storeRef(right)
92
+ .endCell();
93
+ }
94
+ }
95
+ function generateMerkleProofDirect(dict, keys, keyObject) {
96
+ keys.forEach((key) => {
97
+ if (!dict.has(key)) {
98
+ throw new Error(`Trying to generate merkle proof for a missing key "${key}"`);
99
+ }
100
+ });
101
+ const s = (0, core_1.beginCell)().storeDictDirect(dict).asSlice();
102
+ return doGenerateMerkleProof('', s, keyObject.bits, keys.map((key) => keyObject.serialize(key).toString(2).padStart(keyObject.bits, '0')));
103
+ }
104
+ exports.generateMerkleProofDirect = generateMerkleProofDirect;
105
+ function generateMerkleProof(dict, keys, keyObject) {
106
+ return convertToMerkleProof(generateMerkleProofDirect(dict, keys, keyObject));
107
+ }
108
+ exports.generateMerkleProof = generateMerkleProof;
@@ -0,0 +1,55 @@
1
+ /// <reference types="node" />
2
+ import { Cell, Dictionary, Slice } from "@ton/core";
3
+ import { PriceData, RawPriceData } from "../types/Common";
4
+ import { Oracle, PoolAssetsConfig } from "../types/Master";
5
+ type OutputData = {
6
+ metadata: {
7
+ blockId: string;
8
+ transactionId: string;
9
+ outputIndex: number;
10
+ isSpent: boolean;
11
+ milestoneIndexSpent: number;
12
+ milestoneTimestampSpent: number;
13
+ transactionIdSpent: string;
14
+ milestoneIndexBooked: number;
15
+ milestoneTimestampBooked: number;
16
+ ledgerIndex: number;
17
+ };
18
+ output: {
19
+ type: number;
20
+ amount: string;
21
+ nftId: string;
22
+ unlockConditions: {
23
+ type: number;
24
+ address: {
25
+ type: number;
26
+ pubKeyHash: string;
27
+ };
28
+ }[];
29
+ features: {
30
+ type: number;
31
+ data: string;
32
+ }[];
33
+ };
34
+ };
35
+ export type OraclePricesData = {
36
+ timestamp: number;
37
+ prices: Dictionary<bigint, bigint>;
38
+ };
39
+ export declare function loadPrices(oracleNftId: String, endpoints: String[]): Promise<OutputData>;
40
+ export declare function parsePrices(outputData: OutputData, oracleId: number): Promise<RawPriceData>;
41
+ export declare function verifyPrices(assets: PoolAssetsConfig): (priceData: RawPriceData) => boolean;
42
+ export declare function getMedianPrice(pricesData: PriceData[], asset: bigint): bigint;
43
+ export declare function packAssetsData(assetsData: {
44
+ assetId: bigint;
45
+ medianPrice: bigint;
46
+ }[]): Cell;
47
+ export declare function packPrices(assetsDataCell: Cell, oraclesDataCell: Cell): Cell;
48
+ export declare function createOracleDataProof(oracle: Oracle, data: OraclePricesData, signature: Buffer, assets: Array<bigint>): Slice;
49
+ export declare function packOraclesData(oraclesData: {
50
+ oracle: Oracle;
51
+ data: OraclePricesData;
52
+ signature: Buffer;
53
+ }[], assets: Array<bigint>): Cell;
54
+ export declare function sumDicts(result: Dictionary<bigint, bigint>, addendum: Dictionary<bigint, bigint>): void;
55
+ export {};
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sumDicts = exports.packOraclesData = exports.createOracleDataProof = exports.packPrices = exports.packAssetsData = exports.getMedianPrice = exports.verifyPrices = exports.parsePrices = exports.loadPrices = void 0;
4
+ const core_1 = require("@ton/core");
5
+ const config_1 = require("../config");
6
+ const merkleProof_1 = require("./merkleProof");
7
+ async function loadPrices(oracleNftId, endpoints) {
8
+ return await Promise.any(endpoints.map(x => loadOracleData(oracleNftId, x)));
9
+ }
10
+ exports.loadPrices = loadPrices;
11
+ async function loadOracleData(oracleNftId, endpoint) {
12
+ let result = await fetch(`https://${endpoint}/api/indexer/v1/outputs/nft/${oracleNftId}`, {
13
+ headers: { accept: 'application/json' },
14
+ signal: AbortSignal.timeout(5000)
15
+ });
16
+ let outputId = (await result.json());
17
+ result = await fetch(`https://${endpoint}/api/core/v2/outputs/${outputId.items[0]}`, {
18
+ headers: { accept: 'application/json' },
19
+ signal: AbortSignal.timeout(5000)
20
+ });
21
+ return await result.json();
22
+ }
23
+ async function parsePrices(outputData, oracleId) {
24
+ const data = JSON.parse(decodeURIComponent(outputData.output.features[0].data.replace('0x', '').replace(/[0-9a-f]{2}/g, '%$&')));
25
+ try {
26
+ const pricesCell = core_1.Cell.fromBoc(Buffer.from(data['packedPrices'], 'hex'))[0];
27
+ const signature = Buffer.from(data['signature'], 'hex');
28
+ const publicKey = Buffer.from(data['publicKey'], 'hex');
29
+ const timestamp = Number(data['timestamp']);
30
+ return {
31
+ dict: pricesCell.beginParse().loadRef().beginParse().loadDictDirect(core_1.Dictionary.Keys.BigUint(256), core_1.Dictionary.Values.BigVarUint(4)),
32
+ dataCell: (0, core_1.beginCell)().storeRef(pricesCell).storeBuffer(signature).endCell(),
33
+ oracleId: oracleId,
34
+ signature: signature,
35
+ pubkey: publicKey,
36
+ timestamp: timestamp,
37
+ };
38
+ }
39
+ catch (error) {
40
+ console.log(oracleId, data, error);
41
+ throw Error();
42
+ }
43
+ }
44
+ exports.parsePrices = parsePrices;
45
+ function verifyPrices(assets) {
46
+ return function (priceData) {
47
+ const timestamp = Date.now() / 1000;
48
+ const pricesTime = priceData.timestamp;
49
+ for (const asset of assets) {
50
+ if (!priceData.dict.has(asset.assetId)) {
51
+ return false;
52
+ }
53
+ }
54
+ // console.log('timestamp', timestamp, 'pricestime', pricesTime, timestamp - pricesTime);
55
+ return timestamp - pricesTime < config_1.TTL_ORACLE_DATA_SEC;
56
+ };
57
+ }
58
+ exports.verifyPrices = verifyPrices;
59
+ function getMedianPrice(pricesData, asset) {
60
+ const sorted = pricesData.map(x => x.dict.get(asset)).sort((a, b) => Number(a) - Number(b));
61
+ const mid = Math.floor(sorted.length / 2);
62
+ if (sorted.length % 2 === 0) {
63
+ return (sorted[mid - 1] + sorted[mid]) / 2n;
64
+ }
65
+ else {
66
+ return sorted[mid];
67
+ }
68
+ }
69
+ exports.getMedianPrice = getMedianPrice;
70
+ function packAssetsData(assetsData) {
71
+ if (assetsData.length == 0) {
72
+ throw new Error("No assets data to pack");
73
+ }
74
+ return assetsData.reduceRight((acc, { assetId, medianPrice }) => (0, core_1.beginCell)()
75
+ .storeUint(assetId, 256)
76
+ .storeCoins(medianPrice)
77
+ .storeMaybeRef(acc)
78
+ .endCell(), null);
79
+ }
80
+ exports.packAssetsData = packAssetsData;
81
+ function packPrices(assetsDataCell, oraclesDataCell) {
82
+ let pricesCell = (0, core_1.beginCell)()
83
+ .storeRef(assetsDataCell)
84
+ .storeRef(oraclesDataCell)
85
+ .endCell();
86
+ return pricesCell;
87
+ }
88
+ exports.packPrices = packPrices;
89
+ function createOracleDataProof(oracle, data, signature, assets) {
90
+ let prunedDict = (0, merkleProof_1.generateMerkleProofDirect)(data.prices, assets, core_1.Dictionary.Keys.BigUint(256));
91
+ let prunedData = (0, core_1.beginCell)().storeUint(data.timestamp, 32).storeMaybeRef(prunedDict).endCell();
92
+ let merkleProof = (0, merkleProof_1.convertToMerkleProof)(prunedData);
93
+ let oracleDataProof = (0, core_1.beginCell)().storeUint(oracle.id, 32).storeRef(merkleProof).storeBuffer(signature).asSlice();
94
+ return oracleDataProof;
95
+ }
96
+ exports.createOracleDataProof = createOracleDataProof;
97
+ function packOraclesData(oraclesData, assets) {
98
+ if (oraclesData.length == 0) {
99
+ throw new Error("no oracles data to pack");
100
+ }
101
+ let proofs = oraclesData.sort((d1, d2) => d1.oracle.id - d2.oracle.id).map(({ oracle, data, signature }) => createOracleDataProof(oracle, data, signature, assets));
102
+ return proofs.reduceRight((acc, val) => (0, core_1.beginCell)().storeSlice(val).storeMaybeRef(acc).endCell(), null);
103
+ }
104
+ exports.packOraclesData = packOraclesData;
105
+ // : String = "api.stardust-mainnet.iotaledger.net"
106
+ function sumDicts(result, addendum) {
107
+ for (const key of addendum.keys()) {
108
+ const current = result.get(key);
109
+ const value = addendum.get(key);
110
+ if (current === undefined) {
111
+ result.set(key, value);
112
+ continue;
113
+ }
114
+ result.set(key, current + value);
115
+ }
116
+ }
117
+ exports.sumDicts = sumDicts;
@@ -1,3 +1,3 @@
1
1
  import { Address } from '@ton/core';
2
- import { PoolAssetConfig, PoolJettonAssetConfig } from '../types/Master';
3
- export declare function getUserJettonWallet(ownerAddress: Address, poolAssetConfig: PoolAssetConfig & PoolJettonAssetConfig): Address;
2
+ import { PoolAssetConfig } from '../types/Master';
3
+ export declare function getUserJettonWallet(ownerAddress: Address, poolAssetConfig: PoolAssetConfig): Address;
@@ -2,7 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUserJettonWallet = void 0;
4
4
  const core_1 = require("@ton/core");
5
+ const assets_1 = require("../constants/assets");
5
6
  function getUserJettonWallet(ownerAddress, poolAssetConfig) {
7
+ if (poolAssetConfig.name == 'TON' || poolAssetConfig.assetId === assets_1.UNDEFINED_ASSET.assetId) {
8
+ throw new Error(`Cant getUserJettonWallet for ${poolAssetConfig.name} asset`);
9
+ }
6
10
  const jettonMasterAddress = poolAssetConfig.jettonMasterAddress;
7
11
  const jettonWalletCode = poolAssetConfig.jettonWalletCode;
8
12
  if (poolAssetConfig.name === 'USDT') {
@@ -0,0 +1,2 @@
1
+ import { PoolAssetConfig } from "../types/Master";
2
+ export declare function isTonAsset(asset: PoolAssetConfig): boolean;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTonAsset = void 0;
4
+ function isTonAsset(asset) {
5
+ return asset.name === 'TON';
6
+ }
7
+ exports.isTonAsset = isTonAsset;