@evaafi/sdk 0.6.2-a → 0.6.2-c
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.
- package/README.md +2 -1
- package/dist/api/math.d.ts +12 -2
- package/dist/api/math.js +56 -4
- package/dist/api/parser.js +41 -18
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -2
- package/dist/prices/PricesCollector.js +1 -1
- package/dist/types/User.d.ts +10 -1
- package/package.json +9 -9
- package/src/api/math.ts +78 -3
- package/src/api/parser.ts +51 -20
- package/src/index.ts +3 -0
- package/src/prices/PricesCollector.ts +1 -1
- package/src/types/User.ts +11 -1
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -4
- package/dist/constants.d.ts +0 -69
- package/dist/constants.js +0 -83
- package/dist/types/Common.d.ts +0 -14
- package/dist/types/Common.js +0 -2
- package/dist/utils/priceUtils.d.ts +0 -55
- package/dist/utils/priceUtils.js +0 -117
package/README.md
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
The EVAA SDK is designed to easily integrate with the EVAA lending protocol on TON blockchain.
|
|
4
4
|
|
|
5
5
|
## Documentation
|
|
6
|
+
You can find the Typedoc documentation [here](https://evaafi.github.io/sdk/).
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Additional (older) documentation can also be found in the [docs](./docs) folder.
|
package/dist/api/math.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AgregatedBalances, AssetConfig, AssetData, AssetInterest, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants, PoolConfig } from '../types/Master';
|
|
1
|
+
import { AgregatedBalances, AssetApy, AssetConfig, AssetData, AssetInterest, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants, PoolConfig } from '../types/Master';
|
|
2
2
|
import { Dictionary } from '@ton/core';
|
|
3
|
-
import { HealthParamsArgs, LiquidationData, PredictHealthFactorArgs, UserBalance } from '../types/User';
|
|
3
|
+
import { HealthParamsArgs, LiquidationData, PredictAPYArgs, PredictHealthFactorArgs, UserBalance } from '../types/User';
|
|
4
4
|
export declare function mulFactor(decimal: bigint, a: bigint, b: bigint): bigint;
|
|
5
5
|
export declare function mulDiv(x: bigint, y: bigint, z: bigint): bigint;
|
|
6
6
|
export declare function mulDivC(x: bigint, y: bigint, z: bigint): bigint;
|
|
@@ -16,6 +16,7 @@ export declare const BigMath: {
|
|
|
16
16
|
max: typeof bigIntMax;
|
|
17
17
|
};
|
|
18
18
|
export declare function calculatePresentValue(index: bigint, principalValue: bigint, masterConstants: MasterConstants): bigint;
|
|
19
|
+
export declare function getAssetLiquidityMinusReserves(assetData: AssetData, masterConstants: MasterConstants): bigint;
|
|
19
20
|
export declare function calculateCurrentRates(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants): {
|
|
20
21
|
sRate: bigint;
|
|
21
22
|
bRate: bigint;
|
|
@@ -25,6 +26,7 @@ export declare function calculateCurrentRates(assetConfig: AssetConfig, assetDat
|
|
|
25
26
|
};
|
|
26
27
|
export declare function calculateAssetData(assetsConfigDict: ExtendedAssetsConfig, assetsDataDict: Dictionary<bigint, AssetData>, assetId: bigint, masterConstants: MasterConstants): ExtendedAssetData;
|
|
27
28
|
export declare function calculateAssetInterest(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants): AssetInterest;
|
|
29
|
+
export declare function calculateInterestWithSupplyBorrow(totalSupply: bigint, totalBorrow: bigint, assetConfig: AssetConfig, masterConstants: MasterConstants): AssetInterest;
|
|
28
30
|
export declare function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boolean;
|
|
29
31
|
export declare function getAgregatedBalances(assetsData: ExtendedAssetsData, assetsConfig: ExtendedAssetsConfig, principals: Dictionary<bigint, bigint>, prices: Dictionary<bigint, bigint>, masterConstants: MasterConstants): AgregatedBalances;
|
|
30
32
|
export declare function calculateMaximumWithdrawAmount(assetsConfig: ExtendedAssetsConfig, assetsData: ExtendedAssetsData, principals: Dictionary<bigint, bigint>, prices: Dictionary<bigint, bigint>, masterConstants: MasterConstants, assetId: bigint): bigint;
|
|
@@ -59,3 +61,11 @@ export declare function calculateHealthParams(parameters: HealthParamsArgs): {
|
|
|
59
61
|
*/
|
|
60
62
|
export declare function calculateLiquidationData(assetsConfig: ExtendedAssetsConfig, assetsData: ExtendedAssetsData, principals: Dictionary<bigint, bigint>, prices: Dictionary<bigint, bigint>, poolConfig: PoolConfig): LiquidationData;
|
|
61
63
|
export declare function predictHealthFactor(args: PredictHealthFactorArgs): number;
|
|
64
|
+
/**
|
|
65
|
+
* Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
|
|
66
|
+
*
|
|
67
|
+
* Used on the front-end.
|
|
68
|
+
*
|
|
69
|
+
* @returns Estimated APYs for Supply and Borrow
|
|
70
|
+
*/
|
|
71
|
+
export declare function predictAPY(args: PredictAPYArgs): AssetInterest & AssetApy;
|
package/dist/api/math.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.predictHealthFactor = exports.calculateLiquidationData = exports.calculateHealthParams = exports.presentValue = exports.getAvailableToBorrow = exports.calculateMaximumWithdrawAmount = exports.getAgregatedBalances = exports.checkNotInDebtAtAll = exports.calculateAssetInterest = exports.calculateAssetData = exports.calculateCurrentRates = exports.calculatePresentValue = exports.BigMath = exports.bigIntMin = exports.bigIntMax = exports.bigAbs = exports.mulDivC = exports.mulDiv = exports.mulFactor = void 0;
|
|
3
|
+
exports.predictAPY = exports.predictHealthFactor = exports.calculateLiquidationData = exports.calculateHealthParams = exports.presentValue = exports.getAvailableToBorrow = exports.calculateMaximumWithdrawAmount = exports.getAgregatedBalances = exports.checkNotInDebtAtAll = exports.calculateInterestWithSupplyBorrow = exports.calculateAssetInterest = exports.calculateAssetData = exports.calculateCurrentRates = exports.getAssetLiquidityMinusReserves = exports.calculatePresentValue = exports.BigMath = exports.bigIntMin = exports.bigIntMax = exports.bigAbs = exports.mulDivC = exports.mulDiv = exports.mulFactor = void 0;
|
|
4
4
|
const User_1 = require("../types/User");
|
|
5
5
|
const assets_1 = require("../constants/assets");
|
|
6
6
|
const liquidation_1 = require("./liquidation");
|
|
@@ -35,6 +35,12 @@ function calculatePresentValue(index, principalValue, masterConstants) {
|
|
|
35
35
|
return (principalValue * index) / masterConstants.FACTOR_SCALE;
|
|
36
36
|
}
|
|
37
37
|
exports.calculatePresentValue = calculatePresentValue;
|
|
38
|
+
function getAssetLiquidityMinusReserves(assetData, masterConstants) {
|
|
39
|
+
const total_supply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
40
|
+
const total_borrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
41
|
+
return bigIntMin(total_supply - total_borrow, assetData.balance);
|
|
42
|
+
}
|
|
43
|
+
exports.getAssetLiquidityMinusReserves = getAssetLiquidityMinusReserves;
|
|
38
44
|
function calculateCurrentRates(assetConfig, assetData, masterConstants) {
|
|
39
45
|
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
40
46
|
const timeElapsed = now - assetData.lastAccural;
|
|
@@ -81,6 +87,10 @@ exports.calculateAssetData = calculateAssetData;
|
|
|
81
87
|
function calculateAssetInterest(assetConfig, assetData, masterConstants) {
|
|
82
88
|
const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
83
89
|
const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
90
|
+
return calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants);
|
|
91
|
+
}
|
|
92
|
+
exports.calculateAssetInterest = calculateAssetInterest;
|
|
93
|
+
function calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants) {
|
|
84
94
|
let utilization = 0n;
|
|
85
95
|
let supplyInterest = 0n;
|
|
86
96
|
let borrowInterest = 0n;
|
|
@@ -104,7 +114,7 @@ function calculateAssetInterest(assetConfig, assetData, masterConstants) {
|
|
|
104
114
|
borrowInterest
|
|
105
115
|
};
|
|
106
116
|
}
|
|
107
|
-
exports.
|
|
117
|
+
exports.calculateInterestWithSupplyBorrow = calculateInterestWithSupplyBorrow;
|
|
108
118
|
function checkNotInDebtAtAll(principals) {
|
|
109
119
|
return principals.values().every(x => x >= 0n);
|
|
110
120
|
}
|
|
@@ -173,10 +183,16 @@ function getAvailableToBorrow(assetsConfig, assetsData, principals, prices, mast
|
|
|
173
183
|
let borrowLimit = 0n;
|
|
174
184
|
let borrowAmount = 0n;
|
|
175
185
|
for (const assetID of principals.keys()) {
|
|
186
|
+
const principal = principals.get(assetID);
|
|
187
|
+
if (principal == 0n) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (!prices.has(assetID)) {
|
|
191
|
+
return 0n;
|
|
192
|
+
}
|
|
176
193
|
const assetConfig = assetsConfig.get(assetID);
|
|
177
194
|
const assetData = assetsData.get(assetID);
|
|
178
195
|
const price = prices.get(assetID);
|
|
179
|
-
const principal = principals.get(assetID);
|
|
180
196
|
if (principal < 0n) {
|
|
181
197
|
borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
|
|
182
198
|
}
|
|
@@ -359,7 +375,6 @@ function predictHealthFactor(args) {
|
|
|
359
375
|
const assetId = args.asset.assetId;
|
|
360
376
|
const assetConfig = args.assetsConfig.get(assetId);
|
|
361
377
|
const assetPrice = Number(args.prices.get(assetId));
|
|
362
|
-
const assetData = args.assetsData.get(assetId);
|
|
363
378
|
let totalLimit = Number(healthParams.totalLimit);
|
|
364
379
|
let totalBorrow = Number(healthParams.totalDebt);
|
|
365
380
|
const currentAmount = args.amount;
|
|
@@ -386,3 +401,40 @@ function predictHealthFactor(args) {
|
|
|
386
401
|
return Math.min(Math.max(1 - totalBorrow / totalLimit, 0), 1); // let's limit a result to zero below and one above
|
|
387
402
|
}
|
|
388
403
|
exports.predictHealthFactor = predictHealthFactor;
|
|
404
|
+
/**
|
|
405
|
+
* Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
|
|
406
|
+
*
|
|
407
|
+
* Used on the front-end.
|
|
408
|
+
*
|
|
409
|
+
* @returns Estimated APYs for Supply and Borrow
|
|
410
|
+
*/
|
|
411
|
+
function predictAPY(args) {
|
|
412
|
+
const assetConfig = args.assetConfig;
|
|
413
|
+
const assetData = args.assetData;
|
|
414
|
+
const masterConstants = args.masterConstants;
|
|
415
|
+
let totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
416
|
+
let totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
417
|
+
const currentAmount = args.amount;
|
|
418
|
+
const changeType = args.balanceChangeType;
|
|
419
|
+
if (currentAmount != null && currentAmount != 0n) {
|
|
420
|
+
if (changeType == User_1.BalanceChangeType.Borrow) {
|
|
421
|
+
totalBorrow += currentAmount;
|
|
422
|
+
}
|
|
423
|
+
else if (changeType == User_1.BalanceChangeType.Repay) {
|
|
424
|
+
totalBorrow -= currentAmount;
|
|
425
|
+
}
|
|
426
|
+
else if (changeType == User_1.BalanceChangeType.Withdraw) {
|
|
427
|
+
totalSupply -= currentAmount;
|
|
428
|
+
}
|
|
429
|
+
else if (changeType == User_1.BalanceChangeType.Supply) {
|
|
430
|
+
totalSupply += currentAmount;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const interest = calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants);
|
|
434
|
+
return {
|
|
435
|
+
...interest,
|
|
436
|
+
supplyApy: (1 + (Number(interest.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1,
|
|
437
|
+
borrowApy: (1 + (Number(interest.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
exports.predictAPY = predictAPY;
|
package/dist/api/parser.js
CHANGED
|
@@ -24,8 +24,8 @@ function createAssetData() {
|
|
|
24
24
|
serialize: (src, buidler) => {
|
|
25
25
|
buidler.storeUint(src.sRate, 64);
|
|
26
26
|
buidler.storeUint(src.bRate, 64);
|
|
27
|
-
buidler.
|
|
28
|
-
buidler.
|
|
27
|
+
buidler.storeInt(src.totalSupply, 64);
|
|
28
|
+
buidler.storeInt(src.totalBorrow, 64);
|
|
29
29
|
buidler.storeUint(src.lastAccural, 32);
|
|
30
30
|
buidler.storeUint(src.balance, 64);
|
|
31
31
|
buidler.storeUint(src.trackingSupplyIndex, 64);
|
|
@@ -33,15 +33,15 @@ function createAssetData() {
|
|
|
33
33
|
buidler.storeUint(src.awaitedSupply, 64);
|
|
34
34
|
},
|
|
35
35
|
parse: (src) => {
|
|
36
|
-
const sRate = BigInt(src.
|
|
37
|
-
const bRate = BigInt(src.
|
|
38
|
-
const totalSupply = BigInt(src.
|
|
39
|
-
const totalBorrow = BigInt(src.
|
|
40
|
-
const lastAccural = BigInt(src.
|
|
41
|
-
const balance = BigInt(src.
|
|
42
|
-
const trackingSupplyIndex = BigInt(src.
|
|
43
|
-
const trackingBorrowIndex = BigInt(src.
|
|
44
|
-
const awaitedSupply = BigInt(src.
|
|
36
|
+
const sRate = BigInt(src.loadUintBig(64));
|
|
37
|
+
const bRate = BigInt(src.loadUintBig(64));
|
|
38
|
+
const totalSupply = BigInt(src.loadIntBig(64));
|
|
39
|
+
const totalBorrow = BigInt(src.loadIntBig(64));
|
|
40
|
+
const lastAccural = BigInt(src.loadUintBig(32));
|
|
41
|
+
const balance = BigInt(src.loadUintBig(64));
|
|
42
|
+
const trackingSupplyIndex = BigInt(src.loadUintBig(64));
|
|
43
|
+
const trackingBorrowIndex = BigInt(src.loadUintBig(64));
|
|
44
|
+
const awaitedSupply = BigInt(src.loadUintBig(64));
|
|
45
45
|
return { sRate, bRate, totalSupply, totalBorrow, lastAccural, balance, trackingSupplyIndex, trackingBorrowIndex, awaitedSupply };
|
|
46
46
|
},
|
|
47
47
|
};
|
|
@@ -238,6 +238,7 @@ function parseUserLiteData(userDataBOC, assetsData, assetsConfig, poolConfig, ap
|
|
|
238
238
|
trackingBorrowIndex: trackingBorrowIndex,
|
|
239
239
|
dutchAuctionStart: dutchAuctionStart,
|
|
240
240
|
backupCell: backupCell,
|
|
241
|
+
fullyParsed: false,
|
|
241
242
|
rewards: rewards,
|
|
242
243
|
backupCell1: backupCell1,
|
|
243
244
|
backupCell2: backupCell2,
|
|
@@ -245,12 +246,22 @@ function parseUserLiteData(userDataBOC, assetsData, assetsConfig, poolConfig, ap
|
|
|
245
246
|
}
|
|
246
247
|
exports.parseUserLiteData = parseUserLiteData;
|
|
247
248
|
function parseUserData(userLiteData, assetsData, assetsConfig, prices, poolConfig, applyDust = false) {
|
|
249
|
+
userLiteData.fullyParsed = true;
|
|
250
|
+
let havePrincipalWithoutPrice = false;
|
|
248
251
|
const poolAssetsConfig = poolConfig.poolAssetsConfig;
|
|
249
252
|
const masterConstants = poolConfig.masterConstants;
|
|
250
253
|
const withdrawalLimits = core_1.Dictionary.empty();
|
|
251
254
|
const borrowLimits = core_1.Dictionary.empty();
|
|
252
255
|
let supplyBalance = 0n;
|
|
253
256
|
let borrowBalance = 0n;
|
|
257
|
+
for (const [assetId, principal] of userLiteData.realPrincipals) {
|
|
258
|
+
if (!prices.has(assetId)) {
|
|
259
|
+
userLiteData.fullyParsed = false;
|
|
260
|
+
if (principal != 0n) {
|
|
261
|
+
havePrincipalWithoutPrice = true;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
254
265
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
255
266
|
const assetData = assetsData.get(asset.assetId);
|
|
256
267
|
const assetConfig = assetsConfig.get(asset.assetId);
|
|
@@ -263,6 +274,9 @@ function parseUserData(userLiteData, assetsData, assetsConfig, prices, poolConfi
|
|
|
263
274
|
userLiteData.balances.set(asset.assetId, balance);
|
|
264
275
|
}
|
|
265
276
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
277
|
+
if (!prices.has(asset.assetId)) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
266
280
|
const assetConfig = assetsConfig.get(asset.assetId);
|
|
267
281
|
const balance = userLiteData.balances.get(asset.assetId);
|
|
268
282
|
if (balance.type === User_1.BalanceType.supply) {
|
|
@@ -272,24 +286,32 @@ function parseUserData(userLiteData, assetsData, assetsConfig, prices, poolConfi
|
|
|
272
286
|
borrowBalance += (balance.amount * prices.get(asset.assetId)) / 10n ** assetConfig.decimals;
|
|
273
287
|
}
|
|
274
288
|
}
|
|
275
|
-
const availableToBorrow = (0, math_1.getAvailableToBorrow)(assetsConfig, assetsData, userLiteData.
|
|
289
|
+
const availableToBorrow = (0, math_1.getAvailableToBorrow)(assetsConfig, assetsData, userLiteData.realPrincipals, prices, masterConstants);
|
|
276
290
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
291
|
+
const balance = userLiteData.balances.get(asset.assetId);
|
|
277
292
|
const assetConfig = assetsConfig.get(asset.assetId);
|
|
278
293
|
const assetData = assetsData.get(asset.assetId);
|
|
279
|
-
const
|
|
294
|
+
const assetLiquidityMinusReserves = (0, math_1.getAssetLiquidityMinusReserves)(assetData, masterConstants);
|
|
280
295
|
if (balance.type === User_1.BalanceType.supply) {
|
|
281
|
-
withdrawalLimits.set(asset.assetId, (0, math_1.bigIntMin)((0, math_1.calculateMaximumWithdrawAmount)(assetsConfig, assetsData, userLiteData.
|
|
296
|
+
withdrawalLimits.set(asset.assetId, (0, math_1.bigIntMin)((0, math_1.calculateMaximumWithdrawAmount)(assetsConfig, assetsData, userLiteData.realPrincipals, prices, masterConstants, asset.assetId), assetData.balance));
|
|
297
|
+
}
|
|
298
|
+
if (!prices.has(asset.assetId)) {
|
|
299
|
+
borrowLimits.set(asset.assetId, 0n);
|
|
300
|
+
continue;
|
|
282
301
|
}
|
|
283
|
-
borrowLimits.set(asset.assetId, (0, math_1.bigIntMax)(0n, (0, math_1.bigIntMin)((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId),
|
|
302
|
+
borrowLimits.set(asset.assetId, (0, math_1.bigIntMax)(0n, (0, math_1.bigIntMin)((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId), assetLiquidityMinusReserves)));
|
|
284
303
|
}
|
|
285
304
|
const limitUsed = borrowBalance + availableToBorrow;
|
|
286
305
|
const limitUsedPercent = limitUsed === 0n
|
|
287
306
|
? 0
|
|
288
307
|
: Number(BigInt(1e9) - (availableToBorrow * BigInt(1e9)) / (borrowBalance + availableToBorrow)) / 1e7;
|
|
289
|
-
const liquidationData = (0, math_1.calculateLiquidationData)(assetsConfig, assetsData, userLiteData.principals, prices, poolConfig);
|
|
290
308
|
let healthFactor = 1;
|
|
291
|
-
|
|
292
|
-
|
|
309
|
+
let liquidationData;
|
|
310
|
+
if (!havePrincipalWithoutPrice) {
|
|
311
|
+
liquidationData = (0, math_1.calculateLiquidationData)(assetsConfig, assetsData, userLiteData.realPrincipals, prices, poolConfig);
|
|
312
|
+
if (liquidationData.totalLimit != 0n) {
|
|
313
|
+
healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
|
|
314
|
+
}
|
|
293
315
|
}
|
|
294
316
|
return {
|
|
295
317
|
...userLiteData,
|
|
@@ -302,6 +324,7 @@ function parseUserData(userLiteData, assetsData, assetsConfig, prices, poolConfi
|
|
|
302
324
|
limitUsed: limitUsed,
|
|
303
325
|
liquidationData: liquidationData,
|
|
304
326
|
healthFactor: healthFactor,
|
|
327
|
+
havePrincipalWithoutPrice: havePrincipalWithoutPrice
|
|
305
328
|
};
|
|
306
329
|
}
|
|
307
330
|
exports.parseUserData = parseUserData;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { mulFactor, mulDiv, bigIntMin, bigIntMax, calculatePresentValue, calculateCurrentRates, calculateAssetData, calculateAssetInterest, getAvailableToBorrow, calculateMaximumWithdrawAmount, presentValue, calculateLiquidationData, predictHealthFactor, calculateHealthParams, BigMath, } from './api/math';
|
|
1
|
+
export { mulFactor, mulDiv, bigIntMin, bigIntMax, calculatePresentValue, calculateCurrentRates, calculateAssetData, calculateAssetInterest, getAvailableToBorrow, calculateMaximumWithdrawAmount, presentValue, calculateLiquidationData, predictHealthFactor, calculateHealthParams, calculateInterestWithSupplyBorrow, predictAPY, BigMath, getAssetLiquidityMinusReserves, } from './api/math';
|
|
2
2
|
export { calculateLiquidationAmounts, calculateMinCollateralByTransferredAmount, isLiquidatable, isBadDebt, addReserve, deductReserve, addLiquidationBonus, deductLiquidationBonus, toAssetAmount, toAssetWorth, PreparedAssetInfo, PreparedAssetInfoResult, prepareAssetInfo, findAssetById, selectGreatestAssets, calculateAssetsValues, AssetsValues, SelectedAssets, } from './api/liquidation';
|
|
3
3
|
export { createAssetData, createAssetConfig, parseMasterData, parseUserData, parseUserLiteData } from './api/parser';
|
|
4
4
|
export { getPrices } from './api/prices';
|
package/dist/index.js
CHANGED
|
@@ -14,8 +14,8 @@ 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.
|
|
18
|
-
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.NOT_MAINNET = exports.UTON_MAINNET = exports.CATI_MAINNET = exports.DOGS_MAINNET = exports.USDT_STORM_MAINNET = exports.TON_STORM_MAINNET = exports.TONUSDT_DEDUST_MAINNET = exports.USDT_MAINNET = exports.TON_MAINNET = exports.UNDEFINED_ASSET = exports.ASSET_ID = exports.MAINNET_ALTS_POOL_CONFIG = exports.MAINNET_LP_POOL_CONFIG = void 0;
|
|
17
|
+
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.calculateAssetsValues = exports.selectGreatestAssets = exports.findAssetById = exports.prepareAssetInfo = exports.toAssetWorth = exports.toAssetAmount = exports.deductLiquidationBonus = exports.addLiquidationBonus = exports.deductReserve = exports.addReserve = exports.isBadDebt = exports.isLiquidatable = exports.calculateMinCollateralByTransferredAmount = exports.calculateLiquidationAmounts = exports.getAssetLiquidityMinusReserves = exports.BigMath = exports.predictAPY = exports.calculateInterestWithSupplyBorrow = exports.calculateHealthParams = exports.predictHealthFactor = 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
|
+
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.NOT_MAINNET = exports.UTON_MAINNET = exports.CATI_MAINNET = exports.DOGS_MAINNET = exports.USDT_STORM_MAINNET = exports.TON_STORM_MAINNET = exports.TONUSDT_DEDUST_MAINNET = exports.USDT_MAINNET = exports.TON_MAINNET = exports.UNDEFINED_ASSET = exports.ASSET_ID = exports.MAINNET_ALTS_POOL_CONFIG = exports.MAINNET_LP_POOL_CONFIG = exports.TESTNET_POOL_CONFIG = exports.MAINNET_POOL_CONFIG = exports.MASTER_CONSTANTS = void 0;
|
|
19
19
|
// Math
|
|
20
20
|
var math_1 = require("./api/math");
|
|
21
21
|
Object.defineProperty(exports, "mulFactor", { enumerable: true, get: function () { return math_1.mulFactor; } });
|
|
@@ -32,7 +32,10 @@ Object.defineProperty(exports, "presentValue", { enumerable: true, get: function
|
|
|
32
32
|
Object.defineProperty(exports, "calculateLiquidationData", { enumerable: true, get: function () { return math_1.calculateLiquidationData; } });
|
|
33
33
|
Object.defineProperty(exports, "predictHealthFactor", { enumerable: true, get: function () { return math_1.predictHealthFactor; } });
|
|
34
34
|
Object.defineProperty(exports, "calculateHealthParams", { enumerable: true, get: function () { return math_1.calculateHealthParams; } });
|
|
35
|
+
Object.defineProperty(exports, "calculateInterestWithSupplyBorrow", { enumerable: true, get: function () { return math_1.calculateInterestWithSupplyBorrow; } });
|
|
36
|
+
Object.defineProperty(exports, "predictAPY", { enumerable: true, get: function () { return math_1.predictAPY; } });
|
|
35
37
|
Object.defineProperty(exports, "BigMath", { enumerable: true, get: function () { return math_1.BigMath; } });
|
|
38
|
+
Object.defineProperty(exports, "getAssetLiquidityMinusReserves", { enumerable: true, get: function () { return math_1.getAssetLiquidityMinusReserves; } });
|
|
36
39
|
var liquidation_1 = require("./api/liquidation");
|
|
37
40
|
Object.defineProperty(exports, "calculateLiquidationAmounts", { enumerable: true, get: function () { return liquidation_1.calculateLiquidationAmounts; } });
|
|
38
41
|
Object.defineProperty(exports, "calculateMinCollateralByTransferredAmount", { enumerable: true, get: function () { return liquidation_1.calculateMinCollateralByTransferredAmount; } });
|
|
@@ -119,5 +119,5 @@ _PricesCollector_prices = new WeakMap(), _PricesCollector_poolConfig = new WeakM
|
|
|
119
119
|
__classPrivateFieldSet(this, _PricesCollector_prices, __classPrivateFieldGet(this, _PricesCollector_prices, "f").filter((0, utils_1.verifyPricesTimestamp)()), "f");
|
|
120
120
|
return __classPrivateFieldGet(this, _PricesCollector_prices, "f").length;
|
|
121
121
|
}, _PricesCollector_filterEmptyPrincipalsAndAssets = function _PricesCollector_filterEmptyPrincipalsAndAssets(principals) {
|
|
122
|
-
return principals.keys().filter(x => principals.get(x)
|
|
122
|
+
return principals.keys().filter(x => principals.get(x) != 0n).map(x => __classPrivateFieldGet(this, _PricesCollector_poolConfig, "f").poolAssetsConfig.find(asset => asset.assetId == x));
|
|
123
123
|
};
|
package/dist/types/User.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Address, Cell, Dictionary } from '@ton/core';
|
|
2
|
-
import { ExtendedAssetsConfig, ExtendedAssetsData, PoolAssetConfig, PoolConfig } from './Master';
|
|
2
|
+
import { AssetConfig, AssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants, PoolAssetConfig, PoolConfig } from './Master';
|
|
3
3
|
export declare enum BalanceType {
|
|
4
4
|
supply = "supply",
|
|
5
5
|
borrow = "borrow"
|
|
@@ -41,6 +41,7 @@ export type UserLiteData = {
|
|
|
41
41
|
rewards: Dictionary<bigint, UserRewards>;
|
|
42
42
|
backupCell1: Cell | null;
|
|
43
43
|
backupCell2: Cell | null;
|
|
44
|
+
fullyParsed: boolean;
|
|
44
45
|
};
|
|
45
46
|
export type UserDataActive = UserLiteData & {
|
|
46
47
|
withdrawalLimits: Dictionary<bigint, bigint>;
|
|
@@ -53,6 +54,7 @@ export type UserDataActive = UserLiteData & {
|
|
|
53
54
|
limitUsed: bigint;
|
|
54
55
|
healthFactor: number;
|
|
55
56
|
liquidationData: LiquidationData;
|
|
57
|
+
havePrincipalWithoutPrice: boolean;
|
|
56
58
|
};
|
|
57
59
|
export type UserDataInactive = {
|
|
58
60
|
type: 'inactive';
|
|
@@ -85,3 +87,10 @@ export type PredictHealthFactorArgs = {
|
|
|
85
87
|
assetsConfig: ExtendedAssetsConfig;
|
|
86
88
|
poolConfig: PoolConfig;
|
|
87
89
|
};
|
|
90
|
+
export type PredictAPYArgs = {
|
|
91
|
+
balanceChangeType: BalanceChangeType;
|
|
92
|
+
amount: bigint;
|
|
93
|
+
assetData: AssetData;
|
|
94
|
+
assetConfig: AssetConfig;
|
|
95
|
+
masterConstants: MasterConstants;
|
|
96
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evaafi/sdk",
|
|
3
|
-
"version": "0.6.2-
|
|
3
|
+
"version": "0.6.2-c",
|
|
4
4
|
"description": "The EVAA SDK is designed to easily integrate with the EVAA lending protocol on TON blockchain.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@orbs-network/ton-access": "^2.3.3",
|
|
23
23
|
"@ton/core": "0.56.0",
|
|
24
|
-
"@ton/crypto": "
|
|
25
|
-
"@tonconnect/sdk": "
|
|
24
|
+
"@ton/crypto": "3.3.0",
|
|
25
|
+
"@tonconnect/sdk": "3.0.5",
|
|
26
26
|
"@types/jest": "^29.5.12",
|
|
27
27
|
"@types/node": "^20.10.4",
|
|
28
|
-
"crypto-js": "
|
|
29
|
-
"prettier": "
|
|
28
|
+
"crypto-js": "4.2.0",
|
|
29
|
+
"prettier": "3.2.4",
|
|
30
30
|
"ts-jest": "^29.2.4",
|
|
31
31
|
"ts-node": "^10.9.1",
|
|
32
|
-
"typedoc": "
|
|
33
|
-
"typescript": "
|
|
32
|
+
"typedoc": "0.27.4",
|
|
33
|
+
"typescript": "5.3.3"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@ton/core": ">=0.56.0",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"crypto-js": ">=4.2.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@ton/ton": "
|
|
42
|
-
"dotenv": "
|
|
41
|
+
"@ton/ton": "14.0.0",
|
|
42
|
+
"dotenv": "16.4.5"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/api/math.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgregatedBalances,
|
|
3
|
+
AssetApy,
|
|
3
4
|
AssetConfig,
|
|
4
5
|
AssetData,
|
|
5
6
|
AssetInterest,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
BalanceType,
|
|
16
17
|
HealthParamsArgs,
|
|
17
18
|
LiquidationData,
|
|
19
|
+
PredictAPYArgs,
|
|
18
20
|
PredictHealthFactorArgs,
|
|
19
21
|
UserBalance
|
|
20
22
|
} from '../types/User';
|
|
@@ -53,6 +55,12 @@ export function calculatePresentValue(index: bigint, principalValue: bigint, mas
|
|
|
53
55
|
return (principalValue * index) / masterConstants.FACTOR_SCALE;
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
export function getAssetLiquidityMinusReserves(assetData: AssetData, masterConstants: MasterConstants) {
|
|
59
|
+
const total_supply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
60
|
+
const total_borrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
61
|
+
return bigIntMin(total_supply - total_borrow, assetData.balance);
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
export function calculateCurrentRates(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants) {
|
|
57
65
|
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
58
66
|
const timeElapsed = now - assetData.lastAccural;
|
|
@@ -109,9 +117,28 @@ export function calculateAssetData(
|
|
|
109
117
|
};
|
|
110
118
|
}
|
|
111
119
|
|
|
112
|
-
export function calculateAssetInterest(
|
|
120
|
+
export function calculateAssetInterest(
|
|
121
|
+
assetConfig: AssetConfig,
|
|
122
|
+
assetData: AssetData,
|
|
123
|
+
masterConstants: MasterConstants
|
|
124
|
+
): AssetInterest {
|
|
113
125
|
const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
114
126
|
const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
127
|
+
|
|
128
|
+
return calculateInterestWithSupplyBorrow(
|
|
129
|
+
totalSupply,
|
|
130
|
+
totalBorrow,
|
|
131
|
+
assetConfig,
|
|
132
|
+
masterConstants
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function calculateInterestWithSupplyBorrow(
|
|
137
|
+
totalSupply: bigint,
|
|
138
|
+
totalBorrow: bigint,
|
|
139
|
+
assetConfig: AssetConfig,
|
|
140
|
+
masterConstants: MasterConstants
|
|
141
|
+
): AssetInterest {
|
|
115
142
|
let utilization = 0n;
|
|
116
143
|
let supplyInterest = 0n;
|
|
117
144
|
let borrowInterest = 0n;
|
|
@@ -147,6 +174,7 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
|
|
|
147
174
|
};
|
|
148
175
|
}
|
|
149
176
|
|
|
177
|
+
|
|
150
178
|
export function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boolean {
|
|
151
179
|
return principals.values().every(x => x >= 0n);
|
|
152
180
|
}
|
|
@@ -250,10 +278,19 @@ export function getAvailableToBorrow(
|
|
|
250
278
|
let borrowAmount = 0n;
|
|
251
279
|
|
|
252
280
|
for (const assetID of principals.keys()) {
|
|
281
|
+
const principal = principals.get(assetID) as bigint;
|
|
282
|
+
|
|
283
|
+
if (principal == 0n) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!prices.has(assetID)) {
|
|
288
|
+
return 0n;
|
|
289
|
+
}
|
|
290
|
+
|
|
253
291
|
const assetConfig = assetsConfig.get(assetID) as AssetConfig;
|
|
254
292
|
const assetData = assetsData.get(assetID) as ExtendedAssetData;
|
|
255
293
|
const price = prices.get(assetID) as bigint;
|
|
256
|
-
const principal = principals.get(assetID) as bigint;
|
|
257
294
|
|
|
258
295
|
if (principal < 0n) {
|
|
259
296
|
borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
|
|
@@ -464,7 +501,6 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
|
|
|
464
501
|
|
|
465
502
|
const assetConfig = args.assetsConfig.get(assetId)!;
|
|
466
503
|
const assetPrice = Number(args.prices.get(assetId)!);
|
|
467
|
-
const assetData = args.assetsData.get(assetId)!;
|
|
468
504
|
|
|
469
505
|
let totalLimit = Number(healthParams.totalLimit);
|
|
470
506
|
let totalBorrow = Number(healthParams.totalDebt);
|
|
@@ -493,3 +529,42 @@ const assetData = args.assetsData.get(assetId)!;
|
|
|
493
529
|
|
|
494
530
|
return Math.min(Math.max(1 - totalBorrow / totalLimit, 0), 1); // let's limit a result to zero below and one above
|
|
495
531
|
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
|
|
535
|
+
*
|
|
536
|
+
* Used on the front-end.
|
|
537
|
+
*
|
|
538
|
+
* @returns Estimated APYs for Supply and Borrow
|
|
539
|
+
*/
|
|
540
|
+
export function predictAPY(args: PredictAPYArgs): AssetInterest & AssetApy {
|
|
541
|
+
const assetConfig = args.assetConfig;
|
|
542
|
+
const assetData = args.assetData;
|
|
543
|
+
const masterConstants = args.masterConstants;
|
|
544
|
+
|
|
545
|
+
let totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
546
|
+
let totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
547
|
+
|
|
548
|
+
const currentAmount = args.amount;
|
|
549
|
+
const changeType = args.balanceChangeType;
|
|
550
|
+
|
|
551
|
+
if (currentAmount != null && currentAmount != 0n) {
|
|
552
|
+
if (changeType == BalanceChangeType.Borrow) {
|
|
553
|
+
totalBorrow += currentAmount;
|
|
554
|
+
} else if (changeType == BalanceChangeType.Repay) {
|
|
555
|
+
totalBorrow -= currentAmount;
|
|
556
|
+
} else if (changeType == BalanceChangeType.Withdraw) {
|
|
557
|
+
totalSupply -= currentAmount;
|
|
558
|
+
} else if (changeType == BalanceChangeType.Supply) {
|
|
559
|
+
totalSupply += currentAmount;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const interest = calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants);
|
|
564
|
+
|
|
565
|
+
return {
|
|
566
|
+
...interest,
|
|
567
|
+
supplyApy: (1 + (Number(interest.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1,
|
|
568
|
+
borrowApy: (1 + (Number(interest.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1
|
|
569
|
+
}
|
|
570
|
+
}
|
package/src/api/parser.ts
CHANGED
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
calculateLiquidationData,
|
|
8
8
|
calculateMaximumWithdrawAmount,
|
|
9
9
|
calculatePresentValue,
|
|
10
|
+
getAssetLiquidityMinusReserves,
|
|
10
11
|
getAvailableToBorrow,
|
|
11
12
|
presentValue,
|
|
12
13
|
} from './math';
|
|
13
14
|
import { loadMaybeMyRef, loadMyRef } from './helpers';
|
|
14
15
|
import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';
|
|
16
|
+
import { checkNotInDebtAtAll } from "../api/math";
|
|
15
17
|
|
|
16
18
|
export function createUserRewards(): DictionaryValue<UserRewards> {
|
|
17
19
|
return {
|
|
@@ -32,8 +34,8 @@ export function createAssetData(): DictionaryValue<AssetData> {
|
|
|
32
34
|
serialize: (src: any, buidler: any) => {
|
|
33
35
|
buidler.storeUint(src.sRate, 64);
|
|
34
36
|
buidler.storeUint(src.bRate, 64);
|
|
35
|
-
buidler.
|
|
36
|
-
buidler.
|
|
37
|
+
buidler.storeInt(src.totalSupply, 64);
|
|
38
|
+
buidler.storeInt(src.totalBorrow, 64);
|
|
37
39
|
buidler.storeUint(src.lastAccural, 32);
|
|
38
40
|
buidler.storeUint(src.balance, 64);
|
|
39
41
|
buidler.storeUint(src.trackingSupplyIndex, 64);
|
|
@@ -41,15 +43,15 @@ export function createAssetData(): DictionaryValue<AssetData> {
|
|
|
41
43
|
buidler.storeUint(src.awaitedSupply, 64);
|
|
42
44
|
},
|
|
43
45
|
parse: (src: Slice) => {
|
|
44
|
-
const sRate = BigInt(src.
|
|
45
|
-
const bRate = BigInt(src.
|
|
46
|
-
const totalSupply = BigInt(src.
|
|
47
|
-
const totalBorrow = BigInt(src.
|
|
48
|
-
const lastAccural = BigInt(src.
|
|
49
|
-
const balance = BigInt(src.
|
|
50
|
-
const trackingSupplyIndex = BigInt(src.
|
|
51
|
-
const trackingBorrowIndex = BigInt(src.
|
|
52
|
-
const awaitedSupply = BigInt(src.
|
|
46
|
+
const sRate = BigInt(src.loadUintBig(64));
|
|
47
|
+
const bRate = BigInt(src.loadUintBig(64));
|
|
48
|
+
const totalSupply = BigInt(src.loadIntBig(64));
|
|
49
|
+
const totalBorrow = BigInt(src.loadIntBig(64));
|
|
50
|
+
const lastAccural = BigInt(src.loadUintBig(32));
|
|
51
|
+
const balance = BigInt(src.loadUintBig(64));
|
|
52
|
+
const trackingSupplyIndex = BigInt(src.loadUintBig(64));
|
|
53
|
+
const trackingBorrowIndex = BigInt(src.loadUintBig(64));
|
|
54
|
+
const awaitedSupply = BigInt(src.loadUintBig(64));
|
|
53
55
|
|
|
54
56
|
return { sRate, bRate, totalSupply, totalBorrow, lastAccural, balance, trackingSupplyIndex, trackingBorrowIndex, awaitedSupply};
|
|
55
57
|
},
|
|
@@ -267,6 +269,7 @@ export function parseUserLiteData(
|
|
|
267
269
|
trackingBorrowIndex: trackingBorrowIndex,
|
|
268
270
|
dutchAuctionStart: dutchAuctionStart,
|
|
269
271
|
backupCell: backupCell,
|
|
272
|
+
fullyParsed: false,
|
|
270
273
|
|
|
271
274
|
rewards: rewards,
|
|
272
275
|
backupCell1: backupCell1,
|
|
@@ -282,6 +285,9 @@ export function parseUserData(
|
|
|
282
285
|
poolConfig: PoolConfig,
|
|
283
286
|
applyDust: boolean = false
|
|
284
287
|
): UserData {
|
|
288
|
+
userLiteData.fullyParsed = true;
|
|
289
|
+
let havePrincipalWithoutPrice = false;
|
|
290
|
+
|
|
285
291
|
const poolAssetsConfig = poolConfig.poolAssetsConfig;
|
|
286
292
|
const masterConstants = poolConfig.masterConstants;
|
|
287
293
|
|
|
@@ -291,6 +297,16 @@ export function parseUserData(
|
|
|
291
297
|
let supplyBalance = 0n;
|
|
292
298
|
let borrowBalance = 0n;
|
|
293
299
|
|
|
300
|
+
for (const [assetId, principal] of userLiteData.realPrincipals) {
|
|
301
|
+
if (!prices.has(assetId)) {
|
|
302
|
+
userLiteData.fullyParsed = false;
|
|
303
|
+
|
|
304
|
+
if (principal != 0n) {
|
|
305
|
+
havePrincipalWithoutPrice = true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
294
310
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
295
311
|
const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
|
|
296
312
|
const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
|
|
@@ -307,6 +323,10 @@ export function parseUserData(
|
|
|
307
323
|
}
|
|
308
324
|
|
|
309
325
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
326
|
+
if (!prices.has(asset.assetId)) {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
|
|
310
330
|
const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
|
|
311
331
|
const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
|
|
312
332
|
|
|
@@ -318,22 +338,30 @@ export function parseUserData(
|
|
|
318
338
|
}
|
|
319
339
|
}
|
|
320
340
|
|
|
321
|
-
const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.
|
|
341
|
+
const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.realPrincipals, prices, masterConstants);
|
|
342
|
+
|
|
322
343
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
344
|
+
const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
|
|
323
345
|
const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
|
|
324
346
|
const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
|
|
325
|
-
const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
|
|
326
347
|
|
|
348
|
+
const assetLiquidityMinusReserves = getAssetLiquidityMinusReserves(assetData, masterConstants);
|
|
349
|
+
|
|
327
350
|
if (balance.type === BalanceType.supply) {
|
|
328
351
|
withdrawalLimits.set(
|
|
329
352
|
asset.assetId,
|
|
330
|
-
bigIntMin(calculateMaximumWithdrawAmount(assetsConfig, assetsData, userLiteData.
|
|
353
|
+
bigIntMin(calculateMaximumWithdrawAmount(assetsConfig, assetsData, userLiteData.realPrincipals, prices, masterConstants, asset.assetId), assetData.balance)
|
|
331
354
|
);
|
|
332
355
|
}
|
|
333
356
|
|
|
357
|
+
if (!prices.has(asset.assetId)) {
|
|
358
|
+
borrowLimits.set(asset.assetId, 0n);
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
|
|
334
362
|
borrowLimits.set(
|
|
335
363
|
asset.assetId,
|
|
336
|
-
bigIntMax(0n, bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId)!,
|
|
364
|
+
bigIntMax(0n, bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId)!, assetLiquidityMinusReserves)),
|
|
337
365
|
);
|
|
338
366
|
}
|
|
339
367
|
|
|
@@ -343,12 +371,14 @@ export function parseUserData(
|
|
|
343
371
|
? 0
|
|
344
372
|
: Number(BigInt(1e9) - (availableToBorrow * BigInt(1e9)) / (borrowBalance + availableToBorrow)) / 1e7;
|
|
345
373
|
|
|
346
|
-
const liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.principals, prices, poolConfig);
|
|
347
374
|
let healthFactor = 1;
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
375
|
+
let liquidationData;
|
|
376
|
+
if (!havePrincipalWithoutPrice) {
|
|
377
|
+
liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.realPrincipals, prices, poolConfig);
|
|
378
|
+
if (liquidationData.totalLimit != 0n) {
|
|
379
|
+
healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
352
382
|
return {
|
|
353
383
|
...userLiteData,
|
|
354
384
|
withdrawalLimits: withdrawalLimits,
|
|
@@ -360,5 +390,6 @@ export function parseUserData(
|
|
|
360
390
|
limitUsed: limitUsed,
|
|
361
391
|
liquidationData: liquidationData,
|
|
362
392
|
healthFactor: healthFactor,
|
|
393
|
+
havePrincipalWithoutPrice: havePrincipalWithoutPrice
|
|
363
394
|
};
|
|
364
395
|
}
|
package/src/index.ts
CHANGED
|
@@ -134,6 +134,6 @@ export class PricesCollector {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
#filterEmptyPrincipalsAndAssets(principals: Dictionary<bigint, bigint>) {
|
|
137
|
-
return principals.keys().filter(x => principals.get(x)!
|
|
137
|
+
return principals.keys().filter(x => principals.get(x)! != 0n).map(x => this.#poolConfig.poolAssetsConfig.find(asset => asset.assetId == x));
|
|
138
138
|
}
|
|
139
139
|
}
|
package/src/types/User.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Address, BitBuilder, Cell, Dictionary } from '@ton/core';
|
|
2
|
-
import { AssetConfig, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConfig, MasterConstants, PoolAssetConfig, PoolConfig } from './Master';
|
|
2
|
+
import { AssetConfig, AssetData, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConfig, MasterConstants, PoolAssetConfig, PoolConfig } from './Master';
|
|
3
3
|
|
|
4
4
|
export enum BalanceType {
|
|
5
5
|
supply = 'supply',
|
|
@@ -48,6 +48,7 @@ export type UserLiteData = {
|
|
|
48
48
|
rewards: Dictionary<bigint, UserRewards>;
|
|
49
49
|
backupCell1: Cell | null;
|
|
50
50
|
backupCell2: Cell | null;
|
|
51
|
+
fullyParsed: boolean;
|
|
51
52
|
};
|
|
52
53
|
|
|
53
54
|
export type UserDataActive = UserLiteData & {
|
|
@@ -61,6 +62,7 @@ export type UserDataActive = UserLiteData & {
|
|
|
61
62
|
limitUsed: bigint;
|
|
62
63
|
healthFactor: number;
|
|
63
64
|
liquidationData: LiquidationData;
|
|
65
|
+
havePrincipalWithoutPrice: boolean;
|
|
64
66
|
};
|
|
65
67
|
|
|
66
68
|
export type UserDataInactive = {
|
|
@@ -99,3 +101,11 @@ export type PredictHealthFactorArgs = {
|
|
|
99
101
|
assetsConfig: ExtendedAssetsConfig;
|
|
100
102
|
poolConfig: PoolConfig;
|
|
101
103
|
};
|
|
104
|
+
|
|
105
|
+
export type PredictAPYArgs = {
|
|
106
|
+
balanceChangeType: BalanceChangeType;
|
|
107
|
+
amount: bigint; // always positive
|
|
108
|
+
assetData: AssetData;
|
|
109
|
+
assetConfig: AssetConfig;
|
|
110
|
+
masterConstants: MasterConstants;
|
|
111
|
+
};
|
package/dist/config.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const TTL_ORACLE_DATA_SEC = 120;
|
package/dist/config.js
DELETED
package/dist/constants.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { Address, Cell } from '@ton/core';
|
|
2
|
-
import { OracleNFT } from './types/Master';
|
|
3
|
-
export declare const EVAA_MASTER_MAINNET: Address;
|
|
4
|
-
export declare const MAINNET_VERSION = 0;
|
|
5
|
-
export declare const EVAA_MASTER_TESTNET: Address;
|
|
6
|
-
export declare const TESTNET_VERSION = 6;
|
|
7
|
-
export declare const ORACLE_NFTS: OracleNFT[];
|
|
8
|
-
export declare const MAINNET_ASSETS_ID: {
|
|
9
|
-
TON: bigint;
|
|
10
|
-
jUSDT: bigint;
|
|
11
|
-
jUSDC: bigint;
|
|
12
|
-
stTON: bigint;
|
|
13
|
-
tsTON: bigint;
|
|
14
|
-
};
|
|
15
|
-
export declare const TESTNET_ASSETS_ID: {
|
|
16
|
-
TON: bigint;
|
|
17
|
-
jUSDT: bigint;
|
|
18
|
-
jUSDC: bigint;
|
|
19
|
-
stTON: bigint;
|
|
20
|
-
};
|
|
21
|
-
export declare const JETTON_MASTER_ADDRESSES: {
|
|
22
|
-
jUSDT_MAINNET: Address;
|
|
23
|
-
jUSDT_TESTNET: Address;
|
|
24
|
-
jUSDC_MAINNET: Address;
|
|
25
|
-
jUSDC_TESTNET: Address;
|
|
26
|
-
stTON_MAINNET: Address;
|
|
27
|
-
stTON_TESTNET: Address;
|
|
28
|
-
tsTON_MAINNET: Address;
|
|
29
|
-
tsTON_TESTNET: null;
|
|
30
|
-
USDT_MAINNET: Address;
|
|
31
|
-
USDT_TESTNET: null;
|
|
32
|
-
};
|
|
33
|
-
export declare const MASTER_CONSTANTS: {
|
|
34
|
-
FACTOR_SCALE: bigint;
|
|
35
|
-
ASSET_COEFFICIENT_SCALE: bigint;
|
|
36
|
-
ASSET_PRICE_SCALE: bigint;
|
|
37
|
-
ASSET_RESERVE_FACTOR_SCALE: bigint;
|
|
38
|
-
ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: bigint;
|
|
39
|
-
ASSET_ORIGINATION_FEE_SCALE: bigint;
|
|
40
|
-
};
|
|
41
|
-
export declare const LENDING_CODE: Cell;
|
|
42
|
-
export declare const JETTON_WALLETS_CODE: {
|
|
43
|
-
jUSDT_MAINNET: Cell;
|
|
44
|
-
jUSDT_TESTNET: Cell;
|
|
45
|
-
jUSDC_MAINNET: Cell;
|
|
46
|
-
jUSDC_TESTNET: Cell;
|
|
47
|
-
stTON_MAINNET: Cell;
|
|
48
|
-
stTON_TESTNET: Cell;
|
|
49
|
-
tsTON_MAINNET: Cell;
|
|
50
|
-
tsTON_TESTNET: null;
|
|
51
|
-
USDT_MAINNET: Cell;
|
|
52
|
-
USDT_TESTNET: null;
|
|
53
|
-
};
|
|
54
|
-
export declare const OPCODES: {
|
|
55
|
-
SUPPLY: number;
|
|
56
|
-
WITHDRAW: number;
|
|
57
|
-
LIQUIDATE: number;
|
|
58
|
-
JETTON_TRANSFER: number;
|
|
59
|
-
ONCHAIN_GETTER: number;
|
|
60
|
-
};
|
|
61
|
-
export declare const FEES: {
|
|
62
|
-
SUPPLY: bigint;
|
|
63
|
-
WITHDRAW: bigint;
|
|
64
|
-
SUPPLY_JETTON: bigint;
|
|
65
|
-
SUPPLY_JETTON_FWD: bigint;
|
|
66
|
-
LIQUIDATION: bigint;
|
|
67
|
-
LIQUIDATION_JETTON: bigint;
|
|
68
|
-
LIQUIDATION_JETTON_FWD: bigint;
|
|
69
|
-
};
|
package/dist/constants.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FEES = exports.OPCODES = exports.JETTON_WALLETS_CODE = exports.LENDING_CODE = exports.MASTER_CONSTANTS = exports.JETTON_MASTER_ADDRESSES = exports.TESTNET_ASSETS_ID = exports.MAINNET_ASSETS_ID = exports.ORACLE_NFTS = exports.TESTNET_VERSION = exports.EVAA_MASTER_TESTNET = exports.MAINNET_VERSION = exports.EVAA_MASTER_MAINNET = void 0;
|
|
4
|
-
const core_1 = require("@ton/core");
|
|
5
|
-
const sha256BigInt_1 = require("./utils/sha256BigInt");
|
|
6
|
-
//todo set back to EQC8rUZqR_pWV1BylWUlPNBzyiTYVoBEmQkMIQDZXICfnuRr
|
|
7
|
-
exports.EVAA_MASTER_MAINNET = core_1.Address.parse('EQC_hR5L4G3vkPG0VODURYoohp_3hlMW-gZiGp89HwyulZK4');
|
|
8
|
-
//todo set back to 5 (todo set at 6 on 10.10.2024)
|
|
9
|
-
exports.MAINNET_VERSION = 0;
|
|
10
|
-
exports.EVAA_MASTER_TESTNET = core_1.Address.parse('kQC92pF4XWatZY9-ZS6SGW6s-dCpjk9NtEkdXQ7vFHJUAdT9');
|
|
11
|
-
exports.TESTNET_VERSION = 6;
|
|
12
|
-
exports.ORACLE_NFTS = [
|
|
13
|
-
{ id: 0, address: '0xd3a8c0b9fd44fd25a49289c631e3ac45689281f2f8cf0744400b4c65bed38e5d' },
|
|
14
|
-
{ id: 1, address: '0x2c21cabdaa89739de16bde7bc44e86401fac334a3c7e55305fe5e7563043e191' },
|
|
15
|
-
{ id: 2, address: '0x2eb258ce7b5d02466ab8a178ad8b0ba6ffa7b58ef21de3dc3b6dd359a1e16af0' },
|
|
16
|
-
{ id: 3, address: '0xf9a0769954b4430bca95149fb3d876deb7799d8f74852e0ad4ccc5778ce68b52' },
|
|
17
|
-
];
|
|
18
|
-
exports.MAINNET_ASSETS_ID = {
|
|
19
|
-
TON: (0, sha256BigInt_1.sha256Hash)('TON'),
|
|
20
|
-
jUSDT: (0, sha256BigInt_1.sha256Hash)('jUSDT'),
|
|
21
|
-
jUSDC: (0, sha256BigInt_1.sha256Hash)('jUSDC'),
|
|
22
|
-
stTON: (0, sha256BigInt_1.sha256Hash)('stTON'),
|
|
23
|
-
tsTON: (0, sha256BigInt_1.sha256Hash)('tsTON'),
|
|
24
|
-
//todo uncomment
|
|
25
|
-
// USDT: sha256Hash('USDT'),
|
|
26
|
-
};
|
|
27
|
-
exports.TESTNET_ASSETS_ID = {
|
|
28
|
-
TON: (0, sha256BigInt_1.sha256Hash)('TON'),
|
|
29
|
-
jUSDT: (0, sha256BigInt_1.sha256Hash)('jUSDT'),
|
|
30
|
-
jUSDC: (0, sha256BigInt_1.sha256Hash)('jUSDC'),
|
|
31
|
-
stTON: (0, sha256BigInt_1.sha256Hash)('stTON'),
|
|
32
|
-
// tsTON: sha256Hash('tsTON'),
|
|
33
|
-
// USDT: sha256Hash('USDT'),
|
|
34
|
-
};
|
|
35
|
-
exports.JETTON_MASTER_ADDRESSES = {
|
|
36
|
-
jUSDT_MAINNET: core_1.Address.parse('EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA'),
|
|
37
|
-
jUSDT_TESTNET: core_1.Address.parse('kQBe4gtSQMxM5RpMYLr4ydNY72F8JkY-icZXG1NJcsju8XM7'),
|
|
38
|
-
jUSDC_MAINNET: core_1.Address.parse('EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728'),
|
|
39
|
-
jUSDC_TESTNET: core_1.Address.parse('kQDaY5yUatYnHei73HBqRX_Ox9LK2XnR7XuCY9MFC2INbfYI'),
|
|
40
|
-
stTON_MAINNET: core_1.Address.parse('EQDNhy-nxYFgUqzfUzImBEP67JqsyMIcyk2S5_RwNNEYku0k'),
|
|
41
|
-
stTON_TESTNET: core_1.Address.parse('kQC3Duw3dg8k98xf5S7Bm7YOWVJ5QW8hm3iLqFfJfa_g9h07'),
|
|
42
|
-
tsTON_MAINNET: core_1.Address.parse('EQC98_qAmNEptUtPc7W6xdHh_ZHrBUFpw5Ft_IzNU20QAJav'),
|
|
43
|
-
tsTON_TESTNET: null,
|
|
44
|
-
USDT_MAINNET: core_1.Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'),
|
|
45
|
-
USDT_TESTNET: null,
|
|
46
|
-
};
|
|
47
|
-
exports.MASTER_CONSTANTS = {
|
|
48
|
-
FACTOR_SCALE: BigInt(1e12),
|
|
49
|
-
ASSET_COEFFICIENT_SCALE: 10000n,
|
|
50
|
-
ASSET_PRICE_SCALE: BigInt(1e8),
|
|
51
|
-
ASSET_RESERVE_FACTOR_SCALE: 10000n,
|
|
52
|
-
ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: 10000n,
|
|
53
|
-
ASSET_ORIGINATION_FEE_SCALE: BigInt(1e9)
|
|
54
|
-
};
|
|
55
|
-
exports.LENDING_CODE = core_1.Cell.fromBoc(Buffer.from('b5ee9c72c1010e0100fd000d12182a555a6065717691969efd0114ff00f4a413f4bcf2c80b010202c8050202039f740403001ff2f8276a2687d2018fd201800f883b840051d38642c678b64e4400780e58fc10802faf07f80e59fa801e78b096664c02078067c07c100627a7978402014807060007a0ddb0c60201c709080013a0fd007a026900aa90400201200b0a0031b8e1002191960aa00b9e2ca007f4042796d225e8019203f6010201200d0c000bf7c147d2218400b9d10e86981fd201840b07f8138d809797976a2687d2029116382f970fd9178089910374daf81b619fd20182c7883b8701981684100627910eba56001797a6a6ba610fd8200e8768f76a9f6aa00cc2a32a8292878809bef2f1889f883bbcdeb86f01', 'hex'))[0];
|
|
56
|
-
exports.JETTON_WALLETS_CODE = {
|
|
57
|
-
jUSDT_MAINNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c7201021301000385000114ff00f4a413f4bcf2c80b0102016202030202cb0405001ba0f605da89a1f401f481f481a9a30201ce06070201580a0b02f70831c02497c138007434c0c05c6c2544d7c0fc07783e903e900c7e800c5c75c87e800c7e800c1cea6d0000b4c7c076cf16cc8d0d0d09208403e29fa96ea68c1b088d978c4408fc06b809208405e351466ea6cc1b08978c840910c03c06f80dd6cda0841657c1ef2ea7c09c6c3cb4b01408eebcb8b1807c073817c160080900113e910c30003cb85360005c804ff833206e953080b1f833de206ef2d29ad0d30731d3ffd3fff404d307d430d0fa00fa00fa00fa00fa00fa00300008840ff2f00201580c0d020148111201f70174cfc0407e803e90087c007b51343e803e903e903534544da8548b31c17cb8b04ab0bffcb8b0950d109c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c032481c007e401d3232c084b281f2fff274013e903d010c7e800835d270803cb8b13220060072c15401f3c59c3e809dc072dae00e02f33b51343e803e903e90353442b4cfc0407e80145468017e903e9014d771c1551cdbdc150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c0325c007e401d3232c084b281f2fff2741403f1c147ac7cb8b0c33e801472a84a6d8206685401e8062849a49b1578c34975c2c070c00870802c200f1000aa13ccc88210178d4519580a02cb1fcb3f5007fa0222cf165006cf1625fa025003cf16c95005cc2391729171e25007a813a008aa005004a017a014bcf2e2c501c98040fb004300c85004fa0258cf1601cf16ccc9ed5400725269a018a1c882107362d09c2902cb1fcb3f5007fa025004cf165007cf16c9c8801001cb0527cf165004fa027101cb6a13ccc971fb0050421300748e23c8801001cb055006cf165005fa027001cb6a8210d53276db580502cb1fcb3fc972fb00925b33e24003c85004fa0258cf1601cf16ccc9ed5400eb3b51343e803e903e9035344174cfc0407e800870803cb8b0be903d01007434e7f440745458a8549631c17cb8b049b0bffcb8b0b220841ef765f7960100b2c7f2cfc07e8088f3c58073c584f2e7f27220060072c148f3c59c3e809c4072dab33260103ec01004f214013e809633c58073c5b3327b55200087200835c87b51343e803e903e9035344134c7c06103c8608405e351466e80a0841ef765f7ae84ac7cbd34cfc04c3e800c04e81408f214013e809633c58073c5b3327b5520', 'hex'))[0],
|
|
58
|
-
jUSDT_TESTNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c7201021101000323000114ff00f4a413f4bcf2c80b0102016202030202cc0405001ba0f605da89a1f401f481f481a8610201d40607020120080900c30831c02497c138007434c0c05c6c2544d7c0fc03383e903e900c7e800c5c75c87e800c7e800c1cea6d0000b4c7e08403e29fa954882ea54c4d167c0278208405e3514654882ea58c511100fc02b80d60841657c1ef2ea4d67c02f817c12103fcbc2000113e910c1c2ebcb853600201200a0b0083d40106b90f6a2687d007d207d206a1802698fc1080bc6a28ca9105d41083deecbef09dd0958f97162e99f98fd001809d02811e428027d012c678b00e78b6664f6aa401f1503d33ffa00fa4021f001ed44d0fa00fa40fa40d4305136a1522ac705f2e2c128c2fff2e2c254344270542013541403c85004fa0258cf1601cf16ccc922c8cb0112f400f400cb00c920f9007074c8cb02ca07cbffc9d004fa40f40431fa0020d749c200f2e2c4778018c8cb055008cf1670fa0217cb6b13cc80c0201200d0e009e8210178d4519c8cb1f19cb3f5007fa0222cf165006cf1625fa025003cf16c95005cc2391729171e25008a813a08209c9c380a014bcf2e2c504c98040fb001023c85004fa0258cf1601cf16ccc9ed5402f73b51343e803e903e90350c0234cffe80145468017e903e9014d6f1c1551cdb5c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c0327e401c1d3232c0b281f2fff274140371c1472c7cb8b0c2be80146a2860822625a019ad822860822625a028062849e5c412440e0dd7c138c34975c2c0600f1000d73b51343e803e903e90350c01f4cffe803e900c145468549271c17cb8b049f0bffcb8b08160824c4b402805af3cb8b0e0841ef765f7b232c7c572cfd400fe8088b3c58073c5b25c60063232c14933c59c3e80b2dab33260103ec01004f214013e809633c58073c5b3327b552000705279a018a182107362d09cc8cb1f5230cb3f58fa025007cf165007cf16c9718010c8cb0524cf165006fa0215cb6a14ccc971fb0010241023007cc30023c200b08e218210d53276db708010c8cb055008cf165004fa0216cb6a12cb1f12cb3fc972fb0093356c21e203c85004fa0258cf1601cf16ccc9ed54', 'hex'))[0],
|
|
59
|
-
jUSDC_MAINNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c7201021301000385000114ff00f4a413f4bcf2c80b0102016202030202cb0405001ba0f605da89a1f401f481f481a9a30201ce06070201580a0b02f70831c02497c138007434c0c05c6c2544d7c0fc07783e903e900c7e800c5c75c87e800c7e800c1cea6d0000b4c7c076cf16cc8d0d0d09208403e29fa96ea68c1b088d978c4408fc06b809208405e351466ea6cc1b08978c840910c03c06f80dd6cda0841657c1ef2ea7c09c6c3cb4b01408eebcb8b1807c073817c160080900113e910c30003cb85360005c804ff833206e953080b1f833de206ef2d29ad0d30731d3ffd3fff404d307d430d0fa00fa00fa00fa00fa00fa00300008840ff2f00201580c0d020148111201f70174cfc0407e803e90087c007b51343e803e903e903534544da8548b31c17cb8b04ab0bffcb8b0950d109c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c032481c007e401d3232c084b281f2fff274013e903d010c7e800835d270803cb8b13220060072c15401f3c59c3e809dc072dae00e02f33b51343e803e903e90353442b4cfc0407e80145468017e903e9014d771c1551cdbdc150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c0325c007e401d3232c084b281f2fff2741403f1c147ac7cb8b0c33e801472a84a6d8206685401e8062849a49b1578c34975c2c070c00870802c200f1000aa13ccc88210178d4519580a02cb1fcb3f5007fa0222cf165006cf1625fa025003cf16c95005cc2391729171e25007a813a008aa005004a017a014bcf2e2c501c98040fb004300c85004fa0258cf1601cf16ccc9ed5400725269a018a1c882107362d09c2902cb1fcb3f5007fa025004cf165007cf16c9c8801001cb0527cf165004fa027101cb6a13ccc971fb0050421300748e23c8801001cb055006cf165005fa027001cb6a8210d53276db580502cb1fcb3fc972fb00925b33e24003c85004fa0258cf1601cf16ccc9ed5400eb3b51343e803e903e9035344174cfc0407e800870803cb8b0be903d01007434e7f440745458a8549631c17cb8b049b0bffcb8b0b220841ef765f7960100b2c7f2cfc07e8088f3c58073c584f2e7f27220060072c148f3c59c3e809c4072dab33260103ec01004f214013e809633c58073c5b3327b55200087200835c87b51343e803e903e9035344134c7c06103c8608405e351466e80a0841ef765f7ae84ac7cbd34cfc04c3e800c04e81408f214013e809633c58073c5b3327b5520', 'hex'))[0],
|
|
60
|
-
jUSDC_TESTNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c7201021101000323000114ff00f4a413f4bcf2c80b0102016202030202cc0405001ba0f605da89a1f401f481f481a8610201d40607020120080900c30831c02497c138007434c0c05c6c2544d7c0fc03383e903e900c7e800c5c75c87e800c7e800c1cea6d0000b4c7e08403e29fa954882ea54c4d167c0278208405e3514654882ea58c511100fc02b80d60841657c1ef2ea4d67c02f817c12103fcbc2000113e910c1c2ebcb853600201200a0b0083d40106b90f6a2687d007d207d206a1802698fc1080bc6a28ca9105d41083deecbef09dd0958f97162e99f98fd001809d02811e428027d012c678b00e78b6664f6aa401f1503d33ffa00fa4021f001ed44d0fa00fa40fa40d4305136a1522ac705f2e2c128c2fff2e2c254344270542013541403c85004fa0258cf1601cf16ccc922c8cb0112f400f400cb00c920f9007074c8cb02ca07cbffc9d004fa40f40431fa0020d749c200f2e2c4778018c8cb055008cf1670fa0217cb6b13cc80c0201200d0e009e8210178d4519c8cb1f19cb3f5007fa0222cf165006cf1625fa025003cf16c95005cc2391729171e25008a813a08209c9c380a014bcf2e2c504c98040fb001023c85004fa0258cf1601cf16ccc9ed5402f73b51343e803e903e90350c0234cffe80145468017e903e9014d6f1c1551cdb5c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c0327e401c1d3232c0b281f2fff274140371c1472c7cb8b0c2be80146a2860822625a019ad822860822625a028062849e5c412440e0dd7c138c34975c2c0600f1000d73b51343e803e903e90350c01f4cffe803e900c145468549271c17cb8b049f0bffcb8b08160824c4b402805af3cb8b0e0841ef765f7b232c7c572cfd400fe8088b3c58073c5b25c60063232c14933c59c3e80b2dab33260103ec01004f214013e809633c58073c5b3327b552000705279a018a182107362d09cc8cb1f5230cb3f58fa025007cf165007cf16c9718010c8cb0524cf165006fa0215cb6a14ccc971fb0010241023007cc30023c200b08e218210d53276db708010c8cb055008cf165004fa0216cb6a12cb1f12cb3fc972fb0093356c21e203c85004fa0258cf1601cf16ccc9ed54', 'hex'))[0],
|
|
61
|
-
stTON_MAINNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c7201021201000362000114ff00f4a413f4bcf2c80b0102016202030202cc0405001ba0f605da89a1f401f481f481a8610201d40607020120090a01cf0831c02497c138007434c0c05c6c2544d7c0fc03783e903e900c7e800c5c75c87e800c7e800c1cea6d0000b4c7c8608403e29fa96ea54c4d167c02b808608405e351466ea58c511100fc02f80860841657c1ef2ea54c4d167c03380517c1300138c08c2103fcbc200800113e910c30003cb85360007ced44d0fa00fa40fa40d43010235f03018208989680a16d801072226eb32091719170e203c8cb055006cf165004fa02cb6a039358cc019130e201c901fb000201580b0c020148101101f100f4cffe803e90087c007b51343e803e903e90350c144da8548ab1c17cb8b04a30bffcb8b0950d109c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c032483e401c1d3232c0b281f2fff274013e903d010c7e800835d270803cb8b11de0063232c1540233c59c3e8085f2dac4f3200d02f73b51343e803e903e90350c0234cffe80145468017e903e9014d6f1c1551cdb5c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c0327e401c1d3232c0b281f2fff274140371c1472c7cb8b0c2be80146a2860822625a019ad8228608239387028062849e5c412440e0dd7c138c34975c2c0600e0f009e8210178d4519c8cb1f19cb3f5007fa0222cf165006cf1625fa025003cf16c95005cc2391729171e25008a813a0820a625a00a014bcf2e2c504c98040fb001023c85004fa0258cf1601cf16ccc9ed5400705279a018a182107362d09cc8cb1f5230cb3f58fa025007cf165007cf16c9718010c8cb0524cf165006fa0215cb6a14ccc971fb0010241023007cc30023c200b08e218210d53276db708010c8cb055008cf165004fa0216cb6a12cb1f12cb3fc972fb0093356c21e203c85004fa0258cf1601cf16ccc9ed5400c90c3b51343e803e903e90350c01b4cffe800c145128548df1c17cb8b04970bffcb8b0812082e4e1c02fbcb8b160841ef765f7b232c7c532cfd63e808873c5b25c60063232c14933c59c3e80b2dab33260103ec01004f214013e809633c58073c5b3327b55200081200835c87b51343e803e903e90350c0134c7c8608405e351466e80a0841ef765f7ae84ac7cb83234cfcc7e800c04e81408f214013e809633c58073c5b3327b5520', 'hex'))[0],
|
|
62
|
-
stTON_TESTNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c7201021201000362000114ff00f4a413f4bcf2c80b0102016202030202cc0405001ba0f605da89a1f401f481f481a8610201d40607020120090a01cf0831c02497c138007434c0c05c6c2544d7c0fc03383e903e900c7e800c5c75c87e800c7e800c1cea6d0000b4c7c8608403e29fa96ea54c4d167c027808608405e351466ea58c511100fc02b80860841657c1ef2ea54c4d167c02f80517c1300138c08c2103fcbc200800113e910c30003cb85360007ced44d0fa00fa40fa40d43010235f03018208989680a16d801072226eb32091719170e203c8cb055006cf165004fa02cb6a039358cc019130e201c901fb000201200b0c0081d40106b90f6a2687d007d207d206a1802698f90c1080bc6a28cdd0141083deecbef5d0958f97064699f98fd001809d02811e428027d012c678b00e78b6664f6aa401f1503d33ffa00fa4021f001ed44d0fa00fa40fa40d4305136a1522ac705f2e2c128c2fff2e2c254344270542013541403c85004fa0258cf1601cf16ccc922c8cb0112f400f400cb00c920f9007074c8cb02ca07cbffc9d004fa40f40431fa0020d749c200f2e2c4778018c8cb055008cf1670fa0217cb6b13cc80d0201200e0f009e8210178d4519c8cb1f19cb3f5007fa0222cf165006cf1625fa025003cf16c95005cc2391729171e25008a813a0820a625a00a014bcf2e2c504c98040fb001023c85004fa0258cf1601cf16ccc9ed5402f73b51343e803e903e90350c0234cffe80145468017e903e9014d6f1c1551cdb5c150804d50500f214013e809633c58073c5b33248b232c044bd003d0032c0327e401c1d3232c0b281f2fff274140371c1472c7cb8b0c2be80146a2860822625a019ad8228608239387028062849e5c412440e0dd7c138c34975c2c060101100c90c3b51343e803e903e90350c01b4cffe800c145128548df1c17cb8b04970bffcb8b0812082e4e1c02fbcb8b160841ef765f7b232c7c532cfd63e808873c5b25c60063232c14933c59c3e80b2dab33260103ec01004f214013e809633c58073c5b3327b552000705279a018a182107362d09cc8cb1f5230cb3f58fa025007cf165007cf16c9718010c8cb0524cf165006fa0215cb6a14ccc971fb0010241023007cc30023c200b08e218210d53276db708010c8cb055008cf165004fa0216cb6a12cb1f12cb3fc972fb0093356c21e203c85004fa0258cf1601cf16ccc9ed54', 'hex'))[0],
|
|
63
|
-
tsTON_MAINNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c720101010100230000420212bebb0dc8e202b7e26f721e2547e16bb9ebaec934f657d19f22e76d62bec878', 'hex'))[0],
|
|
64
|
-
tsTON_TESTNET: null,
|
|
65
|
-
USDT_MAINNET: core_1.Cell.fromBoc(Buffer.from('b5ee9c72010101010023000042028f452d7a4dfd74066b682365177259ed05734435be76b5fd4bd5d8af2b7c3d68', 'hex'))[0],
|
|
66
|
-
USDT_TESTNET: null,
|
|
67
|
-
};
|
|
68
|
-
exports.OPCODES = {
|
|
69
|
-
SUPPLY: 0x1,
|
|
70
|
-
WITHDRAW: 0x2,
|
|
71
|
-
LIQUIDATE: 0x3,
|
|
72
|
-
JETTON_TRANSFER: 0xf8a7ea5,
|
|
73
|
-
ONCHAIN_GETTER: 0x9998,
|
|
74
|
-
};
|
|
75
|
-
exports.FEES = {
|
|
76
|
-
SUPPLY: (0, core_1.toNano)('0.3'),
|
|
77
|
-
WITHDRAW: (0, core_1.toNano)('0.5'),
|
|
78
|
-
SUPPLY_JETTON: (0, core_1.toNano)('0.8'),
|
|
79
|
-
SUPPLY_JETTON_FWD: (0, core_1.toNano)('0.5'),
|
|
80
|
-
LIQUIDATION: (0, core_1.toNano)('0.8'),
|
|
81
|
-
LIQUIDATION_JETTON: (0, core_1.toNano)('1'),
|
|
82
|
-
LIQUIDATION_JETTON_FWD: (0, core_1.toNano)('0.8'),
|
|
83
|
-
};
|
package/dist/types/Common.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { Cell, Dictionary } from '@ton/core';
|
|
3
|
-
export type RawPriceData = {
|
|
4
|
-
dict: Dictionary<bigint, bigint>;
|
|
5
|
-
dataCell: Cell;
|
|
6
|
-
oracleId: number;
|
|
7
|
-
signature: Buffer;
|
|
8
|
-
pubkey: Buffer;
|
|
9
|
-
timestamp: number;
|
|
10
|
-
};
|
|
11
|
-
export type PriceData = {
|
|
12
|
-
dict: Dictionary<bigint, bigint>;
|
|
13
|
-
dataCell: Cell;
|
|
14
|
-
};
|
package/dist/types/Common.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
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 {};
|
package/dist/utils/priceUtils.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
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;
|