@evaafi/sdk 0.6.1 → 0.6.2-b
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/LICENSE.md +7 -0
- package/README.md +2 -1
- package/dist/api/liquidation.js +1 -3
- package/dist/api/math.d.ts +10 -1
- package/dist/api/math.js +45 -6
- package/dist/api/parser.js +49 -27
- package/dist/api/prices.d.ts +5 -2
- package/dist/api/prices.js +35 -13
- package/dist/constants/assets.d.ts +8 -0
- package/dist/constants/assets.js +31 -1
- package/dist/constants/general.d.ts +5 -2
- package/dist/constants/general.js +12 -22
- package/dist/constants/pools.d.ts +1 -0
- package/dist/constants/pools.js +19 -3
- package/dist/contracts/MasterContract.d.ts +5 -0
- package/dist/contracts/MasterContract.js +6 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +10 -2
- package/dist/prices/Prices.d.ts +9 -0
- package/dist/prices/Prices.js +43 -0
- package/dist/prices/PricesCollector.d.ts +12 -0
- package/dist/prices/PricesCollector.js +123 -0
- package/dist/prices/Types.d.ts +33 -0
- package/dist/prices/Types.js +11 -0
- package/dist/prices/constants.d.ts +1 -0
- package/dist/prices/constants.js +4 -0
- package/dist/prices/index.d.ts +6 -0
- package/dist/prices/index.js +22 -0
- package/dist/prices/sources/Backend.d.ts +13 -0
- package/dist/prices/sources/Backend.js +52 -0
- package/dist/prices/sources/Icp.d.ts +10 -0
- package/dist/prices/sources/Icp.js +23 -0
- package/dist/prices/sources/Iota.d.ts +39 -0
- package/dist/prices/sources/Iota.js +49 -0
- package/dist/prices/sources/PriceSource.d.ts +14 -0
- package/dist/prices/sources/PriceSource.js +26 -0
- package/dist/prices/sources/index.d.ts +4 -0
- package/dist/prices/sources/index.js +20 -0
- package/dist/prices/utils.d.ts +23 -0
- package/dist/prices/utils.js +148 -0
- package/dist/types/Master.d.ts +2 -1
- package/dist/types/User.d.ts +11 -1
- package/dist/utils/userJettonWallet.js +42 -43
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +5 -1
- package/package.json +11 -9
- package/src/api/liquidation.ts +0 -1
- package/src/api/math.ts +66 -5
- package/src/api/parser.ts +56 -31
- package/src/api/prices.ts +20 -7
- package/src/constants/assets.ts +57 -0
- package/src/constants/general.ts +11 -23
- package/src/constants/pools.ts +21 -5
- package/src/contracts/MasterContract.ts +8 -1
- package/src/index.ts +9 -2
- package/src/prices/Prices.ts +32 -0
- package/src/prices/PricesCollector.ts +139 -0
- package/src/prices/Types.ts +44 -0
- package/src/prices/constants.ts +1 -0
- package/src/prices/index.ts +6 -0
- package/src/prices/sources/Backend.ts +62 -0
- package/src/prices/sources/Icp.ts +27 -0
- package/src/prices/sources/Iota.ts +90 -0
- package/src/prices/sources/PriceSource.ts +35 -0
- package/src/prices/sources/index.ts +4 -0
- package/src/prices/utils.ts +170 -0
- package/src/types/Master.ts +3 -2
- package/src/types/User.ts +13 -3
- package/src/utils/userJettonWallet.ts +43 -53
- package/src/utils/utils.ts +5 -1
- package/src/config.ts +0 -1
- package/src/types/Common.ts +0 -16
- package/src/utils/priceUtils.ts +0 -177
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./Backend"), exports);
|
|
18
|
+
__exportStar(require("./Iota"), exports);
|
|
19
|
+
__exportStar(require("./Icp"), exports);
|
|
20
|
+
__exportStar(require("./PriceSource"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Cell, Dictionary, Slice } from "@ton/core";
|
|
3
|
+
import { OraclePricesData, PriceData, PriceSource, PriceSourcesConfig, RawPriceData } from "..";
|
|
4
|
+
import { Oracle, OracleNFT, PoolConfig } from "../types/Master";
|
|
5
|
+
export declare function verifyPricesTimestamp(): (priceData: RawPriceData) => boolean;
|
|
6
|
+
export declare function verifyPricesSign(nfts: OracleNFT[]): (priceData: RawPriceData) => boolean;
|
|
7
|
+
export declare function getMedianPrice(pricesData: PriceData[], asset: bigint): bigint | null;
|
|
8
|
+
export declare function packAssetsData(assetsData: {
|
|
9
|
+
assetId: bigint;
|
|
10
|
+
medianPrice: bigint;
|
|
11
|
+
}[]): Cell;
|
|
12
|
+
export declare function packPrices(assetsDataCell: Cell, oraclesDataCell: Cell): Cell;
|
|
13
|
+
export declare function createOracleDataProof(oracle: Oracle, data: OraclePricesData, signature: Buffer, assets: Array<bigint>): Slice;
|
|
14
|
+
export declare function packOraclesData(oraclesData: {
|
|
15
|
+
oracle: Oracle;
|
|
16
|
+
data: OraclePricesData;
|
|
17
|
+
signature: Buffer;
|
|
18
|
+
}[], assets: Array<bigint>): Cell;
|
|
19
|
+
export declare function sumDicts(result: Dictionary<bigint, bigint>, addendum: Dictionary<bigint, bigint>): void;
|
|
20
|
+
export declare function generatePriceSources(config?: PriceSourcesConfig, nfts?: OracleNFT[]): PriceSource[];
|
|
21
|
+
export declare function collectAndFilterPrices(priceSource: PriceSource, poolConfig: PoolConfig): Promise<RawPriceData[]>;
|
|
22
|
+
export declare function unpackMedianPrices(pricesCell: Cell): Dictionary<bigint, bigint> | undefined;
|
|
23
|
+
export declare function verifyRawPriceDataSign(priceData: RawPriceData): boolean;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyRawPriceDataSign = exports.unpackMedianPrices = exports.collectAndFilterPrices = exports.generatePriceSources = exports.sumDicts = exports.packOraclesData = exports.createOracleDataProof = exports.packPrices = exports.packAssetsData = exports.getMedianPrice = exports.verifyPricesSign = exports.verifyPricesTimestamp = void 0;
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
5
|
+
const __1 = require("..");
|
|
6
|
+
const merkleProof_1 = require("../utils/merkleProof");
|
|
7
|
+
const crypto_1 = require("@ton/crypto");
|
|
8
|
+
function verifyPricesTimestamp() {
|
|
9
|
+
return function (priceData) {
|
|
10
|
+
const timestamp = Date.now() / 1000;
|
|
11
|
+
const pricesTime = priceData.timestamp;
|
|
12
|
+
//console.debug('timestamp - pricesTime, pricesTime', timestamp - pricesTime, pricesTime);
|
|
13
|
+
return timestamp - pricesTime < __1.TTL_ORACLE_DATA_SEC;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
exports.verifyPricesTimestamp = verifyPricesTimestamp;
|
|
17
|
+
function verifyPricesSign(nfts) {
|
|
18
|
+
return function (priceData) {
|
|
19
|
+
if (nfts.findIndex(x => x.pubkey.equals(priceData.pubkey)) == -1) {
|
|
20
|
+
//console.debug('[verifyPricesSign] nft not found');
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return verifyRawPriceDataSign(priceData);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
exports.verifyPricesSign = verifyPricesSign;
|
|
27
|
+
/* export function verifyPricesAssets(assets: PoolAssetsConfig) {
|
|
28
|
+
return function(priceData: RawPriceData): boolean {
|
|
29
|
+
for (const asset of assets) {
|
|
30
|
+
if(!priceData.dict.has(asset.assetId)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
} */
|
|
37
|
+
function getMedianPrice(pricesData, asset) {
|
|
38
|
+
try {
|
|
39
|
+
const usingPrices = pricesData.filter(x => x.dict.has(asset));
|
|
40
|
+
const sorted = usingPrices.map(x => x.dict.get(asset)).sort((a, b) => Number(a) - Number(b));
|
|
41
|
+
if (sorted.length == 0) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const mid = Math.floor(sorted.length / 2);
|
|
45
|
+
if (sorted.length % 2 === 0) {
|
|
46
|
+
return (sorted[mid - 1] + sorted[mid]) / 2n;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return sorted[mid];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.getMedianPrice = getMedianPrice;
|
|
57
|
+
function packAssetsData(assetsData) {
|
|
58
|
+
if (assetsData.length == 0) {
|
|
59
|
+
throw new Error("No assets data to pack");
|
|
60
|
+
}
|
|
61
|
+
return assetsData.reduceRight((acc, { assetId, medianPrice }) => (0, core_1.beginCell)()
|
|
62
|
+
.storeUint(assetId, 256)
|
|
63
|
+
.storeCoins(medianPrice)
|
|
64
|
+
.storeMaybeRef(acc)
|
|
65
|
+
.endCell(), null);
|
|
66
|
+
}
|
|
67
|
+
exports.packAssetsData = packAssetsData;
|
|
68
|
+
function packPrices(assetsDataCell, oraclesDataCell) {
|
|
69
|
+
let pricesCell = (0, core_1.beginCell)()
|
|
70
|
+
.storeRef(assetsDataCell)
|
|
71
|
+
.storeRef(oraclesDataCell)
|
|
72
|
+
.endCell();
|
|
73
|
+
return pricesCell;
|
|
74
|
+
}
|
|
75
|
+
exports.packPrices = packPrices;
|
|
76
|
+
function createOracleDataProof(oracle, data, signature, assets) {
|
|
77
|
+
let prunedDict = (0, merkleProof_1.generateMerkleProofDirect)(data.prices, assets, core_1.Dictionary.Keys.BigUint(256));
|
|
78
|
+
let prunedData = (0, core_1.beginCell)().storeUint(data.timestamp, 32).storeMaybeRef(prunedDict).endCell();
|
|
79
|
+
let merkleProof = (0, merkleProof_1.convertToMerkleProof)(prunedData);
|
|
80
|
+
let oracleDataProof = (0, core_1.beginCell)().storeUint(oracle.id, 32).storeRef(merkleProof).storeBuffer(signature).asSlice();
|
|
81
|
+
return oracleDataProof;
|
|
82
|
+
}
|
|
83
|
+
exports.createOracleDataProof = createOracleDataProof;
|
|
84
|
+
function packOraclesData(oraclesData, assets) {
|
|
85
|
+
if (oraclesData.length == 0) {
|
|
86
|
+
throw new Error("no oracles data to pack");
|
|
87
|
+
}
|
|
88
|
+
let proofs = oraclesData.sort((d1, d2) => d1.oracle.id - d2.oracle.id).map(({ oracle, data, signature }) => createOracleDataProof(oracle, data, signature, assets));
|
|
89
|
+
return proofs.reduceRight((acc, val) => (0, core_1.beginCell)().storeSlice(val).storeMaybeRef(acc).endCell(), null);
|
|
90
|
+
}
|
|
91
|
+
exports.packOraclesData = packOraclesData;
|
|
92
|
+
function sumDicts(result, addendum) {
|
|
93
|
+
for (const key of addendum.keys()) {
|
|
94
|
+
const current = result.get(key);
|
|
95
|
+
const value = addendum.get(key);
|
|
96
|
+
if (current === undefined) {
|
|
97
|
+
result.set(key, value);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
result.set(key, current + value);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.sumDicts = sumDicts;
|
|
104
|
+
function generatePriceSources(config = __1.DefaultPriceSourcesConfig, nfts = __1.MAINNET_POOL_CONFIG.oracles) {
|
|
105
|
+
let result = config.backendEndpoints.map(x => new __1.BackendPriceSource(x, nfts));
|
|
106
|
+
result.push(...config.icpEndpoints.map(x => new __1.IcpPriceSource(x, nfts)));
|
|
107
|
+
result.push(...config.iotaEndpoints.map(x => new __1.IotaPriceSource(x, nfts)));
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
exports.generatePriceSources = generatePriceSources;
|
|
111
|
+
async function collectAndFilterPrices(priceSource, poolConfig) {
|
|
112
|
+
const prices = await priceSource.getPrices();
|
|
113
|
+
//console.debug('[FILTERING] before filtering prices len ', priceSource.sourceName, prices.length);
|
|
114
|
+
return await (async () => {
|
|
115
|
+
const acceptedPrices = prices.filter(price => verifyPricesTimestamp()(price) && verifyPricesSign(poolConfig.oracles)(price));
|
|
116
|
+
//console.debug('[FILTERING] after filtering prices len ', priceSource.sourceName, acceptedPrices.length);
|
|
117
|
+
if (acceptedPrices.length < poolConfig.minimalOracles) {
|
|
118
|
+
throw new Error("Prices are outdated");
|
|
119
|
+
}
|
|
120
|
+
return acceptedPrices;
|
|
121
|
+
})();
|
|
122
|
+
}
|
|
123
|
+
exports.collectAndFilterPrices = collectAndFilterPrices;
|
|
124
|
+
function unpackMedianPrices(pricesCell) {
|
|
125
|
+
if (!pricesCell)
|
|
126
|
+
return undefined;
|
|
127
|
+
const slice = pricesCell.beginParse();
|
|
128
|
+
let assetCell = slice.loadRef();
|
|
129
|
+
const res = core_1.Dictionary.empty();
|
|
130
|
+
while (assetCell != core_1.Cell.EMPTY && assetCell !== null) {
|
|
131
|
+
const slice = assetCell.beginParse();
|
|
132
|
+
const assetId = slice.loadUintBig(256);
|
|
133
|
+
const medianPrice = slice.loadCoins();
|
|
134
|
+
res.set(assetId, medianPrice);
|
|
135
|
+
assetCell = slice.loadMaybeRef();
|
|
136
|
+
}
|
|
137
|
+
return res;
|
|
138
|
+
}
|
|
139
|
+
exports.unpackMedianPrices = unpackMedianPrices;
|
|
140
|
+
function verifyRawPriceDataSign(priceData) {
|
|
141
|
+
const message = priceData.dataCell.refs[0].hash();
|
|
142
|
+
const signature = priceData.signature;
|
|
143
|
+
const publicKey = priceData.pubkey;
|
|
144
|
+
const valid = (0, crypto_1.signVerify)(message, signature, publicKey);
|
|
145
|
+
//console.debug('[verifyRawPriceDataSign] sign is valid:', valid);
|
|
146
|
+
return valid;
|
|
147
|
+
}
|
|
148
|
+
exports.verifyRawPriceDataSign = verifyRawPriceDataSign;
|
package/dist/types/Master.d.ts
CHANGED
|
@@ -80,7 +80,7 @@ export type AssetData = {
|
|
|
80
80
|
balance: bigint;
|
|
81
81
|
trackingSupplyIndex: bigint;
|
|
82
82
|
trackingBorrowIndex: bigint;
|
|
83
|
-
awaitedSupply
|
|
83
|
+
awaitedSupply: bigint;
|
|
84
84
|
};
|
|
85
85
|
export type AssetInterest = {
|
|
86
86
|
supplyInterest: bigint;
|
|
@@ -112,6 +112,7 @@ export type AgregatedBalances = {
|
|
|
112
112
|
export type OracleNFT = {
|
|
113
113
|
id: number;
|
|
114
114
|
address: string;
|
|
115
|
+
pubkey: Buffer;
|
|
115
116
|
};
|
|
116
117
|
export type Oracle = {
|
|
117
118
|
id: number;
|
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"
|
|
@@ -31,6 +31,7 @@ export type UserLiteData = {
|
|
|
31
31
|
masterAddress: Address;
|
|
32
32
|
ownerAddress: Address;
|
|
33
33
|
principals: Dictionary<bigint, bigint>;
|
|
34
|
+
realPrincipals: Dictionary<bigint, bigint>;
|
|
34
35
|
state: number;
|
|
35
36
|
balances: Dictionary<bigint, UserBalance>;
|
|
36
37
|
trackingSupplyIndex: bigint;
|
|
@@ -40,6 +41,7 @@ export type UserLiteData = {
|
|
|
40
41
|
rewards: Dictionary<bigint, UserRewards>;
|
|
41
42
|
backupCell1: Cell | null;
|
|
42
43
|
backupCell2: Cell | null;
|
|
44
|
+
fullyParsed: boolean;
|
|
43
45
|
};
|
|
44
46
|
export type UserDataActive = UserLiteData & {
|
|
45
47
|
withdrawalLimits: Dictionary<bigint, bigint>;
|
|
@@ -52,6 +54,7 @@ export type UserDataActive = UserLiteData & {
|
|
|
52
54
|
limitUsed: bigint;
|
|
53
55
|
healthFactor: number;
|
|
54
56
|
liquidationData: LiquidationData;
|
|
57
|
+
havePrincipalWithoutPrice: boolean;
|
|
55
58
|
};
|
|
56
59
|
export type UserDataInactive = {
|
|
57
60
|
type: 'inactive';
|
|
@@ -84,3 +87,10 @@ export type PredictHealthFactorArgs = {
|
|
|
84
87
|
assetsConfig: ExtendedAssetsConfig;
|
|
85
88
|
poolConfig: PoolConfig;
|
|
86
89
|
};
|
|
90
|
+
export type PredictAPYArgs = {
|
|
91
|
+
balanceChangeType: BalanceChangeType;
|
|
92
|
+
amount: bigint;
|
|
93
|
+
assetData: AssetData;
|
|
94
|
+
assetConfig: AssetConfig;
|
|
95
|
+
masterConstants: MasterConstants;
|
|
96
|
+
};
|
|
@@ -3,54 +3,53 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getUserJettonWallet = void 0;
|
|
4
4
|
const core_1 = require("@ton/core");
|
|
5
5
|
const assets_1 = require("../constants/assets");
|
|
6
|
+
function getUserJettonData(ownerAddress, assetName, jettonWalletCode, jettonMasterAddress) {
|
|
7
|
+
switch (assetName) {
|
|
8
|
+
case 'uTON':
|
|
9
|
+
return (0, core_1.beginCell)()
|
|
10
|
+
.storeCoins(0)
|
|
11
|
+
.storeUint(0, 64)
|
|
12
|
+
.storeAddress(ownerAddress)
|
|
13
|
+
.storeAddress(jettonMasterAddress)
|
|
14
|
+
.storeRef(jettonWalletCode)
|
|
15
|
+
.endCell();
|
|
16
|
+
case 'DOGS':
|
|
17
|
+
case 'NOT':
|
|
18
|
+
case 'USDT':
|
|
19
|
+
return (0, core_1.beginCell)()
|
|
20
|
+
.storeUint(0, 4)
|
|
21
|
+
.storeCoins(0)
|
|
22
|
+
.storeAddress(ownerAddress)
|
|
23
|
+
.storeAddress(jettonMasterAddress)
|
|
24
|
+
.endCell();
|
|
25
|
+
case 'tsTON':
|
|
26
|
+
return (0, core_1.beginCell)()
|
|
27
|
+
.storeCoins(0)
|
|
28
|
+
.storeAddress(ownerAddress)
|
|
29
|
+
.storeAddress(jettonMasterAddress)
|
|
30
|
+
.storeRef(jettonWalletCode)
|
|
31
|
+
.storeCoins(0)
|
|
32
|
+
.storeUint(0, 48)
|
|
33
|
+
.endCell();
|
|
34
|
+
default:
|
|
35
|
+
return (0, core_1.beginCell)().storeCoins(0)
|
|
36
|
+
.storeAddress(ownerAddress)
|
|
37
|
+
.storeAddress(jettonMasterAddress)
|
|
38
|
+
.storeRef(jettonWalletCode)
|
|
39
|
+
.endCell();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
6
42
|
function getUserJettonWallet(ownerAddress, poolAssetConfig) {
|
|
7
|
-
|
|
43
|
+
const assetName = poolAssetConfig.name;
|
|
44
|
+
if (assetName == 'TON' || poolAssetConfig.assetId === assets_1.UNDEFINED_ASSET.assetId) {
|
|
8
45
|
throw new Error(`Cant getUserJettonWallet for ${poolAssetConfig.name} asset`);
|
|
9
46
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (poolAssetConfig.name === 'USDT') {
|
|
47
|
+
let jettonWalletCode = poolAssetConfig.jettonWalletCode;
|
|
48
|
+
if (assetName === 'USDT' || assetName === 'tsTON') {
|
|
13
49
|
const lib_prep = (0, core_1.beginCell)().storeUint(2, 8).storeBuffer(jettonWalletCode.hash()).endCell();
|
|
14
|
-
|
|
15
|
-
const jettonData = (0, core_1.beginCell)()
|
|
16
|
-
.storeUint(0, 4)
|
|
17
|
-
.storeCoins(0)
|
|
18
|
-
.storeAddress(ownerAddress)
|
|
19
|
-
.storeAddress(jettonMasterAddress)
|
|
20
|
-
.endCell();
|
|
21
|
-
const stateInit = (0, core_1.beginCell)()
|
|
22
|
-
.store((0, core_1.storeStateInit)({
|
|
23
|
-
code: jwallet_code,
|
|
24
|
-
data: jettonData
|
|
25
|
-
}))
|
|
26
|
-
.endCell();
|
|
27
|
-
return new core_1.Address(0, stateInit.hash());
|
|
50
|
+
jettonWalletCode = new core_1.Cell({ exotic: true, bits: lib_prep.bits, refs: lib_prep.refs });
|
|
28
51
|
}
|
|
29
|
-
|
|
30
|
-
const lib_prep = (0, core_1.beginCell)().storeUint(2, 8).storeBuffer(jettonWalletCode.hash()).endCell();
|
|
31
|
-
const jwallet_code = new core_1.Cell({ exotic: true, bits: lib_prep.bits, refs: lib_prep.refs });
|
|
32
|
-
const jettonData = (0, core_1.beginCell)()
|
|
33
|
-
.storeCoins(0)
|
|
34
|
-
.storeAddress(ownerAddress)
|
|
35
|
-
.storeAddress(jettonMasterAddress)
|
|
36
|
-
.storeRef(jwallet_code)
|
|
37
|
-
.storeCoins(0)
|
|
38
|
-
.storeUint(0, 48)
|
|
39
|
-
.endCell();
|
|
40
|
-
const stateInit = (0, core_1.beginCell)()
|
|
41
|
-
.store((0, core_1.storeStateInit)({
|
|
42
|
-
code: jwallet_code,
|
|
43
|
-
data: jettonData
|
|
44
|
-
}))
|
|
45
|
-
.endCell();
|
|
46
|
-
return new core_1.Address(0, stateInit.hash());
|
|
47
|
-
}
|
|
48
|
-
const jettonData = (0, core_1.beginCell)()
|
|
49
|
-
.storeCoins(0)
|
|
50
|
-
.storeAddress(ownerAddress)
|
|
51
|
-
.storeAddress(jettonMasterAddress)
|
|
52
|
-
.storeRef(jettonWalletCode)
|
|
53
|
-
.endCell();
|
|
52
|
+
const jettonData = getUserJettonData(ownerAddress, assetName, jettonWalletCode, poolAssetConfig.jettonMasterAddress);
|
|
54
53
|
const stateInit = (0, core_1.beginCell)()
|
|
55
54
|
.store((0, core_1.storeStateInit)({
|
|
56
55
|
code: jettonWalletCode,
|
package/dist/utils/utils.d.ts
CHANGED
package/dist/utils/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isTonAssetId = exports.isTonAsset = void 0;
|
|
3
|
+
exports.delay = exports.isTonAssetId = exports.isTonAsset = void 0;
|
|
4
4
|
const assets_1 = require("../constants/assets");
|
|
5
5
|
function isTonAsset(asset) {
|
|
6
6
|
return asset.name === 'TON';
|
|
@@ -10,3 +10,7 @@ function isTonAssetId(assetId) {
|
|
|
10
10
|
return assetId === assets_1.ASSET_ID.TON;
|
|
11
11
|
}
|
|
12
12
|
exports.isTonAssetId = isTonAssetId;
|
|
13
|
+
function delay(ms) {
|
|
14
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
16
|
+
exports.delay = delay;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evaafi/sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2-b",
|
|
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": [
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"src"
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc --declaration"
|
|
11
|
+
"build": "tsc --declaration",
|
|
12
|
+
"test": "jest"
|
|
12
13
|
},
|
|
13
14
|
"repository": {
|
|
14
15
|
"type": "git",
|
|
@@ -20,15 +21,16 @@
|
|
|
20
21
|
"devDependencies": {
|
|
21
22
|
"@orbs-network/ton-access": "^2.3.3",
|
|
22
23
|
"@ton/core": "0.56.0",
|
|
23
|
-
"@ton/crypto": "
|
|
24
|
-
"@tonconnect/sdk": "
|
|
24
|
+
"@ton/crypto": "3.3.0",
|
|
25
|
+
"@tonconnect/sdk": "3.0.5",
|
|
25
26
|
"@types/jest": "^29.5.12",
|
|
26
27
|
"@types/node": "^20.10.4",
|
|
27
|
-
"crypto-js": "
|
|
28
|
-
"prettier": "
|
|
28
|
+
"crypto-js": "4.2.0",
|
|
29
|
+
"prettier": "3.2.4",
|
|
29
30
|
"ts-jest": "^29.2.4",
|
|
30
31
|
"ts-node": "^10.9.1",
|
|
31
|
-
"
|
|
32
|
+
"typedoc": "0.27.4",
|
|
33
|
+
"typescript": "5.3.3"
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
|
34
36
|
"@ton/core": ">=0.56.0",
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
"crypto-js": ">=4.2.0"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@ton/ton": "
|
|
40
|
-
"dotenv": "
|
|
41
|
+
"@ton/ton": "14.0.0",
|
|
42
|
+
"dotenv": "16.4.5"
|
|
41
43
|
}
|
|
42
44
|
}
|
package/src/api/liquidation.ts
CHANGED
|
@@ -179,7 +179,6 @@ export function calculateLiquidationAmounts(
|
|
|
179
179
|
|
|
180
180
|
const loanValue = toAssetWorth(loanInfo.balance, loanInfo.scale, loanInfo.price);
|
|
181
181
|
const baseLiquidationValue = BigMath.min(
|
|
182
|
-
// deductReserve(loanValue, reserveFactor, reserveFactorScale),
|
|
183
182
|
loanValue,
|
|
184
183
|
deductLiquidationBonus(allowedCollateralValue, liquidationBonus, liquidationBonusScale)
|
|
185
184
|
);
|
package/src/api/math.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
BalanceType,
|
|
16
16
|
HealthParamsArgs,
|
|
17
17
|
LiquidationData,
|
|
18
|
+
PredictAPYArgs,
|
|
18
19
|
PredictHealthFactorArgs,
|
|
19
20
|
UserBalance
|
|
20
21
|
} from '../types/User';
|
|
@@ -109,9 +110,28 @@ export function calculateAssetData(
|
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
112
|
|
|
112
|
-
export function calculateAssetInterest(
|
|
113
|
+
export function calculateAssetInterest(
|
|
114
|
+
assetConfig: AssetConfig,
|
|
115
|
+
assetData: AssetData,
|
|
116
|
+
masterConstants: MasterConstants
|
|
117
|
+
): AssetInterest {
|
|
113
118
|
const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
114
119
|
const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
120
|
+
|
|
121
|
+
return calculateInterestWithSupplyBorrow(
|
|
122
|
+
totalSupply,
|
|
123
|
+
totalBorrow,
|
|
124
|
+
assetConfig,
|
|
125
|
+
masterConstants
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function calculateInterestWithSupplyBorrow(
|
|
130
|
+
totalSupply: bigint,
|
|
131
|
+
totalBorrow: bigint,
|
|
132
|
+
assetConfig: AssetConfig,
|
|
133
|
+
masterConstants: MasterConstants
|
|
134
|
+
): AssetInterest {
|
|
115
135
|
let utilization = 0n;
|
|
116
136
|
let supplyInterest = 0n;
|
|
117
137
|
let borrowInterest = 0n;
|
|
@@ -147,6 +167,7 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
|
|
|
147
167
|
};
|
|
148
168
|
}
|
|
149
169
|
|
|
170
|
+
|
|
150
171
|
export function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boolean {
|
|
151
172
|
return principals.values().every(x => x >= 0n);
|
|
152
173
|
}
|
|
@@ -170,13 +191,12 @@ export function getAgregatedBalances(
|
|
|
170
191
|
const price = prices.get(assetId)!;
|
|
171
192
|
const assetData = assetsData.get(assetId)!;
|
|
172
193
|
const assetConfig = assetsConfig.get(assetId)!;
|
|
173
|
-
|
|
194
|
+
|
|
174
195
|
if (principal < 0) {
|
|
175
196
|
user_total_borrow += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
|
|
176
197
|
} else {
|
|
177
198
|
user_total_supply += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
|
|
178
199
|
}
|
|
179
|
-
// console.log('aggregated', assetId, presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).type, presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals)
|
|
180
200
|
}
|
|
181
201
|
}
|
|
182
202
|
return { totalSupply: user_total_supply, totalBorrow: user_total_borrow };
|
|
@@ -251,10 +271,19 @@ export function getAvailableToBorrow(
|
|
|
251
271
|
let borrowAmount = 0n;
|
|
252
272
|
|
|
253
273
|
for (const assetID of principals.keys()) {
|
|
274
|
+
const principal = principals.get(assetID) as bigint;
|
|
275
|
+
|
|
276
|
+
if (principal == 0n) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!prices.has(assetID)) {
|
|
281
|
+
return 0n;
|
|
282
|
+
}
|
|
283
|
+
|
|
254
284
|
const assetConfig = assetsConfig.get(assetID) as AssetConfig;
|
|
255
285
|
const assetData = assetsData.get(assetID) as ExtendedAssetData;
|
|
256
286
|
const price = prices.get(assetID) as bigint;
|
|
257
|
-
const principal = principals.get(assetID) as bigint;
|
|
258
287
|
|
|
259
288
|
if (principal < 0n) {
|
|
260
289
|
borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
|
|
@@ -465,7 +494,6 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
|
|
|
465
494
|
|
|
466
495
|
const assetConfig = args.assetsConfig.get(assetId)!;
|
|
467
496
|
const assetPrice = Number(args.prices.get(assetId)!);
|
|
468
|
-
const assetData = args.assetsData.get(assetId)!;
|
|
469
497
|
|
|
470
498
|
let totalLimit = Number(healthParams.totalLimit);
|
|
471
499
|
let totalBorrow = Number(healthParams.totalDebt);
|
|
@@ -494,3 +522,36 @@ const assetData = args.assetsData.get(assetId)!;
|
|
|
494
522
|
|
|
495
523
|
return Math.min(Math.max(1 - totalBorrow / totalLimit, 0), 1); // let's limit a result to zero below and one above
|
|
496
524
|
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
|
|
528
|
+
*
|
|
529
|
+
* Used on the front-end.
|
|
530
|
+
*
|
|
531
|
+
* @returns Estimated APYs for Supply and Borrow
|
|
532
|
+
*/
|
|
533
|
+
export function predictAPY(args: PredictAPYArgs): AssetInterest {
|
|
534
|
+
const assetConfig = args.assetConfig;
|
|
535
|
+
const assetData = args.assetData;
|
|
536
|
+
const masterConstants = args.masterConstants;
|
|
537
|
+
|
|
538
|
+
let totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
539
|
+
let totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
540
|
+
|
|
541
|
+
const currentAmount = args.amount;
|
|
542
|
+
const changeType = args.balanceChangeType;
|
|
543
|
+
|
|
544
|
+
if (currentAmount != null && currentAmount != 0n) {
|
|
545
|
+
if (changeType == BalanceChangeType.Borrow) {
|
|
546
|
+
totalBorrow += currentAmount;
|
|
547
|
+
} else if (changeType == BalanceChangeType.Repay) {
|
|
548
|
+
totalBorrow -= currentAmount;
|
|
549
|
+
} else if (changeType == BalanceChangeType.Withdraw) {
|
|
550
|
+
totalSupply -= currentAmount;
|
|
551
|
+
} else if (changeType == BalanceChangeType.Supply) {
|
|
552
|
+
totalSupply += currentAmount;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants);
|
|
557
|
+
}
|