@evaafi/sdk 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/api/feeds.d.ts +30 -0
  2. package/dist/api/feeds.js +73 -0
  3. package/dist/api/liquidation.js +1 -1
  4. package/dist/api/math.js +1 -1
  5. package/dist/api/parser.d.ts +4 -2
  6. package/dist/api/parser.js +39 -18
  7. package/dist/api/parsers/AbstractOracleParser.d.ts +11 -0
  8. package/dist/api/parsers/AbstractOracleParser.js +9 -0
  9. package/dist/api/parsers/ClassicOracleParser.d.ts +10 -0
  10. package/dist/api/parsers/ClassicOracleParser.js +16 -0
  11. package/dist/api/parsers/PythOracleParser.d.ts +17 -0
  12. package/dist/api/parsers/PythOracleParser.js +22 -0
  13. package/dist/api/parsers/index.d.ts +3 -0
  14. package/dist/api/parsers/index.js +19 -0
  15. package/dist/api/prices.d.ts +6 -6
  16. package/dist/api/prices.js +37 -46
  17. package/dist/api/pyth.d.ts +16 -0
  18. package/dist/api/pyth.js +35 -0
  19. package/dist/constants/assets/assetId.d.ts +22 -0
  20. package/dist/constants/assets/assetId.js +29 -0
  21. package/dist/constants/assets/index.d.ts +3 -0
  22. package/dist/constants/assets/index.js +19 -0
  23. package/dist/constants/assets/mainnet.d.ts +19 -0
  24. package/dist/constants/assets/mainnet.js +114 -0
  25. package/dist/constants/assets/testnet.d.ts +14 -0
  26. package/dist/constants/assets/testnet.js +54 -0
  27. package/dist/constants/general/index.d.ts +65 -0
  28. package/dist/constants/general/index.js +93 -0
  29. package/dist/constants/general/mainnet.d.ts +24 -0
  30. package/dist/constants/general/mainnet.js +53 -0
  31. package/dist/constants/general/testnet.d.ts +12 -0
  32. package/dist/constants/general/testnet.js +15 -0
  33. package/dist/constants/general.d.ts +2 -2
  34. package/dist/constants/general.js +4 -4
  35. package/dist/constants/index.d.ts +3 -0
  36. package/dist/constants/index.js +19 -0
  37. package/dist/constants/pools/index.d.ts +2 -0
  38. package/dist/constants/pools/index.js +18 -0
  39. package/dist/constants/pools/mainnet.d.ts +14 -0
  40. package/dist/constants/pools/mainnet.js +145 -0
  41. package/dist/constants/pools/testnet.d.ts +9 -0
  42. package/dist/constants/pools/testnet.js +57 -0
  43. package/dist/constants/pools.js +7 -7
  44. package/dist/contracts/AbstractMaster.d.ts +185 -0
  45. package/dist/contracts/AbstractMaster.js +179 -0
  46. package/dist/contracts/ClassicMaster.d.ts +34 -0
  47. package/dist/contracts/ClassicMaster.js +87 -0
  48. package/dist/contracts/PythMaster.d.ts +61 -0
  49. package/dist/contracts/PythMaster.js +179 -0
  50. package/dist/contracts/UserContract.d.ts +1 -7
  51. package/dist/contracts/UserContract.js +1 -19
  52. package/dist/contracts/index.d.ts +5 -0
  53. package/dist/contracts/index.js +21 -0
  54. package/dist/index.d.ts +14 -14
  55. package/dist/index.js +20 -60
  56. package/dist/prices/Oracle.interface.d.ts +9 -0
  57. package/dist/prices/Oracle.interface.js +2 -0
  58. package/dist/prices/Prices.d.ts +5 -3
  59. package/dist/prices/Prices.js +13 -3
  60. package/dist/prices/PricesCollector.d.ts +17 -7
  61. package/dist/prices/PricesCollector.js +67 -51
  62. package/dist/prices/PythCollector.d.ts +22 -0
  63. package/dist/prices/PythCollector.js +217 -0
  64. package/dist/prices/Types.d.ts +17 -1
  65. package/dist/prices/Types.js +8 -1
  66. package/dist/prices/index.d.ts +4 -3
  67. package/dist/prices/index.js +4 -3
  68. package/dist/prices/sources/Backend.d.ts +5 -4
  69. package/dist/prices/sources/Backend.js +16 -13
  70. package/dist/prices/sources/Icp.d.ts +2 -1
  71. package/dist/prices/sources/Icp.js +12 -9
  72. package/dist/prices/sources/PriceSource.d.ts +7 -6
  73. package/dist/prices/utils.d.ts +10 -8
  74. package/dist/prices/utils.js +32 -46
  75. package/dist/types/Master.d.ts +10 -30
  76. package/dist/types/Master.js +3 -0
  77. package/dist/utils/userJettonWallet.js +0 -8
  78. package/dist/utils/utils.d.ts +8 -1
  79. package/dist/utils/utils.js +31 -2
  80. package/package.json +3 -2
  81. package/src/api/feeds.ts +90 -0
  82. package/src/api/liquidation.ts +1 -1
  83. package/src/api/math.ts +1 -1
  84. package/src/api/parser.ts +100 -38
  85. package/src/api/parsers/AbstractOracleParser.ts +16 -0
  86. package/src/api/parsers/ClassicOracleParser.ts +20 -0
  87. package/src/api/parsers/PythOracleParser.ts +34 -0
  88. package/src/api/parsers/index.ts +3 -0
  89. package/src/api/prices.ts +32 -41
  90. package/src/constants/assets/assetId.ts +30 -0
  91. package/src/constants/assets/index.ts +3 -0
  92. package/src/constants/{assets.ts → assets/mainnet.ts} +3 -96
  93. package/src/constants/assets/testnet.ts +74 -0
  94. package/src/constants/general/index.ts +91 -0
  95. package/src/constants/{general.ts → general/mainnet.ts} +48 -72
  96. package/src/constants/general/testnet.ts +25 -0
  97. package/src/constants/index.ts +3 -0
  98. package/src/constants/pools/index.ts +2 -0
  99. package/src/constants/pools/mainnet.ts +218 -0
  100. package/src/constants/pools/testnet.ts +75 -0
  101. package/src/contracts/AbstractMaster.ts +450 -0
  102. package/src/contracts/ClassicMaster.ts +149 -0
  103. package/src/contracts/PythMaster.ts +313 -0
  104. package/src/contracts/UserContract.ts +7 -28
  105. package/src/contracts/index.ts +7 -0
  106. package/src/index.ts +18 -85
  107. package/src/prices/Oracle.interface.ts +18 -0
  108. package/src/prices/Prices.ts +17 -4
  109. package/src/prices/PricesCollector.ts +91 -68
  110. package/src/prices/PythCollector.ts +294 -0
  111. package/src/prices/Types.ts +28 -6
  112. package/src/prices/index.ts +4 -3
  113. package/src/prices/sources/Backend.ts +21 -19
  114. package/src/prices/sources/Icp.ts +13 -10
  115. package/src/prices/sources/PriceSource.ts +6 -5
  116. package/src/prices/utils.ts +65 -68
  117. package/src/types/Master.ts +29 -52
  118. package/src/types/User.ts +15 -7
  119. package/src/utils/userJettonWallet.ts +0 -8
  120. package/src/utils/utils.ts +41 -2
  121. package/src/constants/pools.ts +0 -177
  122. package/src/contracts/MasterContract.ts +0 -410
@@ -2,22 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IcpPriceSource = void 0;
4
4
  const _1 = require(".");
5
+ const utils_1 = require("../../utils/utils");
5
6
  class IcpPriceSource extends _1.BackendPriceSource {
6
7
  constructor() {
7
8
  super(...arguments);
8
9
  this.priceSourceName = 'IcpPriceSource';
9
10
  }
10
- async loadOracleData() {
11
- let response = await fetch(`https://${this._endpoint}/prices`, {
11
+ async loadOracleData(fetchConfig = utils_1.DefaultFetchConfig) {
12
+ const fetchPromise = fetch(`https://${this._endpoint}/prices`, {
12
13
  headers: { accept: 'application/json' },
13
- signal: AbortSignal.timeout(5000)
14
+ signal: AbortSignal.timeout(fetchConfig.timeout)
15
+ }).then(async (response) => {
16
+ const data = (await response.json());
17
+ let outputData = [];
18
+ for (const nft of this._nfts) {
19
+ outputData.push({ oracleId: nft.id, data: data[nft.address] });
20
+ }
21
+ return outputData;
14
22
  });
15
- const data = (await response.json());
16
- let outputData = [];
17
- for (const nft of this._nfts) {
18
- outputData.push({ oracleId: nft.id, data: data[nft.address] });
19
- }
20
- return outputData;
23
+ return await (0, utils_1.proxyFetchRetries)(fetchPromise, fetchConfig);
21
24
  }
22
25
  }
23
26
  exports.IcpPriceSource = IcpPriceSource;
@@ -1,14 +1,15 @@
1
1
  import { RawPriceData } from "..";
2
- import { OracleNFT } from "../../types/Master";
2
+ import { ExtendedEvaaOracle } from "../../types/Master";
3
+ import { FetchConfig } from "../../utils/utils";
3
4
  export declare abstract class PriceSource {
4
5
  protected priceSourceName: string;
5
6
  protected _endpoint: string;
6
- protected _nfts: OracleNFT[];
7
- constructor(endpoint: string, nfts: OracleNFT[]);
7
+ protected _nfts: ExtendedEvaaOracle[];
8
+ constructor(endpoint: string, nfts: ExtendedEvaaOracle[]);
8
9
  get sourceName(): string;
9
10
  get endpoint(): string;
10
- get nfts(): OracleNFT[];
11
+ get nfts(): ExtendedEvaaOracle[];
11
12
  set endpoint(endpoint: string);
12
- set nfts(nfts: OracleNFT[]);
13
- abstract getPrices(): Promise<RawPriceData[]>;
13
+ set nfts(nfts: ExtendedEvaaOracle[]);
14
+ abstract getPrices(fetchConfig?: FetchConfig): Promise<RawPriceData[]>;
14
15
  }
@@ -1,23 +1,25 @@
1
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";
2
+ import { Cell, Dictionary, Slice } from '@ton/core';
3
+ import { EvaaOracle, ExtendedEvaaOracle } from '../types/Master';
4
+ import { FetchConfig } from '../utils/utils';
5
+ import { PriceSource } from './sources/PriceSource';
6
+ import { OraclePricesData, PriceData, PriceSourcesConfig, RawPriceData } from './Types';
5
7
  export declare function verifyPricesTimestamp(): (priceData: RawPriceData) => boolean;
6
- export declare function verifyPricesSign(nfts: OracleNFT[]): (priceData: RawPriceData) => boolean;
7
8
  export declare function getMedianPrice(pricesData: PriceData[], asset: bigint): bigint | null;
8
9
  export declare function packAssetsData(assetsData: {
9
10
  assetId: bigint;
10
11
  medianPrice: bigint;
11
12
  }[]): Cell;
12
13
  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 createOracleDataProof(oracle: EvaaOracle, data: OraclePricesData, signature: Buffer, assets: Array<bigint>): Slice;
14
15
  export declare function packOraclesData(oraclesData: {
15
- oracle: Oracle;
16
+ oracle: EvaaOracle;
16
17
  data: OraclePricesData;
17
18
  signature: Buffer;
18
19
  }[], assets: Array<bigint>): Cell;
19
20
  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[]>;
21
+ export declare function generatePriceSources(config: PriceSourcesConfig, nfts: ExtendedEvaaOracle[]): PriceSource[];
22
+ export declare function collectAndFilterPrices(priceSource: PriceSource, minimalOracles: number, fetchConfig?: FetchConfig): Promise<RawPriceData[]>;
22
23
  export declare function unpackMedianPrices(pricesCell: Cell): Dictionary<bigint, bigint> | undefined;
24
+ export declare function verifyPricesSign(nfts: ExtendedEvaaOracle[]): (priceData: RawPriceData) => boolean;
23
25
  export declare function verifyRawPriceDataSign(priceData: RawPriceData): boolean;
@@ -1,43 +1,24 @@
1
1
  "use strict";
2
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;
3
+ exports.verifyRawPriceDataSign = exports.verifyPricesSign = exports.unpackMedianPrices = exports.collectAndFilterPrices = exports.generatePriceSources = exports.sumDicts = exports.packOraclesData = exports.createOracleDataProof = exports.packPrices = exports.packAssetsData = exports.getMedianPrice = exports.verifyPricesTimestamp = void 0;
4
4
  const core_1 = require("@ton/core");
5
5
  const crypto_1 = require("@ton/crypto");
6
- const __1 = require("..");
7
6
  const merkleProof_1 = require("../utils/merkleProof");
7
+ const constants_1 = require("./constants");
8
+ const Backend_1 = require("./sources/Backend");
9
+ const Icp_1 = require("./sources/Icp");
8
10
  function verifyPricesTimestamp() {
9
11
  return function (priceData) {
10
12
  const timestamp = Date.now() / 1000;
11
13
  const pricesTime = priceData.timestamp;
12
- //console.debug('timestamp - pricesTime, pricesTime', timestamp - pricesTime, pricesTime);
13
- return timestamp - pricesTime < __1.TTL_ORACLE_DATA_SEC;
14
+ return timestamp - pricesTime < constants_1.TTL_ORACLE_DATA_SEC;
14
15
  };
15
16
  }
16
17
  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
18
  function getMedianPrice(pricesData, asset) {
38
19
  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));
20
+ const usingPrices = pricesData.filter((x) => x.dict.has(asset));
21
+ const sorted = usingPrices.map((x) => x.dict.get(asset)).sort((a, b) => Number(a) - Number(b));
41
22
  if (sorted.length == 0) {
42
23
  return null;
43
24
  }
@@ -56,20 +37,13 @@ function getMedianPrice(pricesData, asset) {
56
37
  exports.getMedianPrice = getMedianPrice;
57
38
  function packAssetsData(assetsData) {
58
39
  if (assetsData.length == 0) {
59
- throw new Error("No assets data to pack");
40
+ throw new Error('No assets data to pack');
60
41
  }
61
- return assetsData.reduceRight((acc, { assetId, medianPrice }) => (0, core_1.beginCell)()
62
- .storeUint(assetId, 256)
63
- .storeCoins(medianPrice)
64
- .storeMaybeRef(acc)
65
- .endCell(), null);
42
+ return assetsData.reduceRight((acc, { assetId, medianPrice }) => (0, core_1.beginCell)().storeUint(assetId, 256).storeCoins(medianPrice).storeMaybeRef(acc).endCell(), null);
66
43
  }
67
44
  exports.packAssetsData = packAssetsData;
68
45
  function packPrices(assetsDataCell, oraclesDataCell) {
69
- let pricesCell = (0, core_1.beginCell)()
70
- .storeRef(assetsDataCell)
71
- .storeRef(oraclesDataCell)
72
- .endCell();
46
+ let pricesCell = (0, core_1.beginCell)().storeRef(assetsDataCell).storeRef(oraclesDataCell).endCell();
73
47
  return pricesCell;
74
48
  }
75
49
  exports.packPrices = packPrices;
@@ -83,9 +57,11 @@ function createOracleDataProof(oracle, data, signature, assets) {
83
57
  exports.createOracleDataProof = createOracleDataProof;
84
58
  function packOraclesData(oraclesData, assets) {
85
59
  if (oraclesData.length == 0) {
86
- throw new Error("no oracles data to pack");
60
+ throw new Error('no oracles data to pack');
87
61
  }
88
- let proofs = oraclesData.sort((d1, d2) => d1.oracle.id - d2.oracle.id).map(({ oracle, data, signature }) => createOracleDataProof(oracle, data, signature, assets));
62
+ let proofs = oraclesData
63
+ .sort((d1, d2) => d1.oracle.id - d2.oracle.id)
64
+ .map(({ oracle, data, signature }) => createOracleDataProof(oracle, data, signature, assets));
89
65
  return proofs.reduceRight((acc, val) => (0, core_1.beginCell)().storeSlice(val).storeMaybeRef(acc).endCell(), null);
90
66
  }
91
67
  exports.packOraclesData = packOraclesData;
@@ -101,20 +77,20 @@ function sumDicts(result, addendum) {
101
77
  }
102
78
  }
103
79
  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)));
80
+ function generatePriceSources(config, nfts) {
81
+ let result = config.backendEndpoints.map((x) => new Backend_1.BackendPriceSource(x, nfts));
82
+ result.push(...config.icpEndpoints.map((x) => new Icp_1.IcpPriceSource(x, nfts)));
107
83
  return result;
108
84
  }
109
85
  exports.generatePriceSources = generatePriceSources;
110
- async function collectAndFilterPrices(priceSource, poolConfig) {
111
- const prices = await priceSource.getPrices();
86
+ async function collectAndFilterPrices(priceSource, minimalOracles, fetchConfig) {
87
+ const prices = await priceSource.getPrices(fetchConfig);
112
88
  //console.debug('[FILTERING] before filtering prices len ', priceSource.sourceName, prices.length);
113
89
  return (async () => {
114
- const acceptedPrices = prices.filter(price => verifyPricesTimestamp()(price) && verifyPricesSign(poolConfig.oracles)(price));
90
+ const acceptedPrices = prices.filter((price) => verifyPricesTimestamp()(price) && verifyPricesSign(priceSource.nfts)(price));
115
91
  //console.debug('[FILTERING] after filtering prices len ', priceSource.sourceName, acceptedPrices.length);
116
- if (acceptedPrices.length < poolConfig.minimalOracles) {
117
- throw new Error("Prices are outdated");
92
+ if (acceptedPrices.length < minimalOracles) {
93
+ throw new Error('Prices are outdated');
118
94
  }
119
95
  return acceptedPrices;
120
96
  })();
@@ -136,6 +112,16 @@ function unpackMedianPrices(pricesCell) {
136
112
  return res;
137
113
  }
138
114
  exports.unpackMedianPrices = unpackMedianPrices;
115
+ function verifyPricesSign(nfts) {
116
+ return function (priceData) {
117
+ if (nfts.findIndex((x) => x.pubkey.equals(priceData.pubkey)) == -1) {
118
+ //console.debug('[verifyPricesSign] nft not found');
119
+ return false;
120
+ }
121
+ return verifyRawPriceDataSign(priceData);
122
+ };
123
+ }
124
+ exports.verifyPricesSign = verifyPricesSign;
139
125
  function verifyRawPriceDataSign(priceData) {
140
126
  const message = priceData.dataCell.refs[0].hash();
141
127
  const signature = priceData.signature;
@@ -1,5 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { Address, Cell, Dictionary } from '@ton/core';
3
+ import { Oracle } from '../prices/Oracle.interface';
4
+ export { FeedMapItem, parseFeedsMapDict } from '../api/feeds';
3
5
  export type MasterConstants = {
4
6
  FACTOR_SCALE: bigint;
5
7
  ASSET_COEFFICIENT_SCALE: bigint;
@@ -24,10 +26,9 @@ export type PoolConfig = {
24
26
  masterAddress: Address;
25
27
  masterVersion: number;
26
28
  masterConstants: MasterConstants;
27
- oracles: OracleNFT[];
28
- minimalOracles: number;
29
29
  poolAssetsConfig: PoolAssetsConfig;
30
30
  lendingCode: Cell;
31
+ oracles: Oracle;
31
32
  };
32
33
  export type UpgradeConfig = {
33
34
  masterCodeVersion: number;
@@ -40,7 +41,7 @@ export type UpgradeConfig = {
40
41
  newUserCode: Cell | null;
41
42
  };
42
43
  export type AssetConfig = {
43
- oracle: bigint;
44
+ jwAddress: bigint;
44
45
  decimals: bigint;
45
46
  collateralFactor: bigint;
46
47
  liquidationThreshold: bigint;
@@ -59,17 +60,10 @@ export type AssetConfig = {
59
60
  minPrincipalForRewards: bigint;
60
61
  baseTrackingSupplySpeed: bigint;
61
62
  baseTrackingBorrowSpeed: bigint;
62
- };
63
- export type MasterConfig = {
64
- ifActive: number;
65
- admin: Address;
66
- oraclesInfo: OraclesInfo;
67
- tokenKeys: Cell | null;
68
- };
69
- export type OraclesInfo = {
70
- numOracles: number;
71
- threshold: number;
72
- oracles: Cell | null;
63
+ borrowCap: number | bigint;
64
+ heCategory: number;
65
+ heCollateralFactor: number;
66
+ heLiquidationThreshold: number;
73
67
  };
74
68
  export type AssetData = {
75
69
  sRate: bigint;
@@ -93,28 +87,14 @@ export type AssetApy = {
93
87
  export type ExtendedAssetData = AssetData & AssetInterest & AssetApy;
94
88
  export type ExtendedAssetsData = Dictionary<bigint, ExtendedAssetData>;
95
89
  export type ExtendedAssetsConfig = Dictionary<bigint, AssetConfig>;
96
- export type MasterData = {
97
- meta: string;
98
- upgradeConfig: UpgradeConfig;
99
- masterConfig: MasterConfig;
100
- assetsConfig: ExtendedAssetsConfig;
101
- assetsData: ExtendedAssetsData;
102
- assetsReserves: Dictionary<bigint, bigint>;
103
- apy: {
104
- supply: Dictionary<bigint, number>;
105
- borrow: Dictionary<bigint, number>;
106
- };
107
- };
108
90
  export type AgregatedBalances = {
109
91
  totalBorrow: bigint;
110
92
  totalSupply: bigint;
111
93
  };
112
- export type OracleNFT = {
113
- id: number;
94
+ export type ExtendedEvaaOracle = EvaaOracle & {
114
95
  address: string;
115
- pubkey: Buffer;
116
96
  };
117
- export type Oracle = {
97
+ export type EvaaOracle = {
118
98
  id: number;
119
99
  pubkey: Buffer;
120
100
  };
@@ -1,2 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFeedsMapDict = void 0;
4
+ var feeds_1 = require("../api/feeds");
5
+ Object.defineProperty(exports, "parseFeedsMapDict", { enumerable: true, get: function () { return feeds_1.parseFeedsMapDict; } });
@@ -5,14 +5,6 @@ const core_1 = require("@ton/core");
5
5
  const assets_1 = require("../constants/assets");
6
6
  function getUserJettonData(ownerAddress, assetName, jettonWalletCode, jettonMasterAddress) {
7
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
8
  case 'DOGS':
17
9
  case 'NOT':
18
10
  case 'USDT':
@@ -1,4 +1,11 @@
1
- import { PoolAssetConfig } from "../types/Master";
1
+ import { PoolAssetConfig } from '../types/Master';
2
2
  export declare function isTonAsset(asset: PoolAssetConfig): boolean;
3
3
  export declare function isTonAssetId(assetId: bigint): boolean;
4
4
  export declare function delay(ms: number): Promise<unknown>;
5
+ export interface FetchConfig {
6
+ retries: number;
7
+ timeout: number;
8
+ }
9
+ export declare const DefaultFetchConfig: FetchConfig;
10
+ export declare function proxyFetchRetries<T>(fetch: Promise<T>, config?: FetchConfig): Promise<T>;
11
+ export declare function isValidSubaccountId(subaccountId: number): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.delay = exports.isTonAssetId = exports.isTonAsset = void 0;
3
+ exports.isValidSubaccountId = exports.proxyFetchRetries = exports.DefaultFetchConfig = 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';
@@ -11,6 +11,35 @@ function isTonAssetId(assetId) {
11
11
  }
12
12
  exports.isTonAssetId = isTonAssetId;
13
13
  function delay(ms) {
14
- return new Promise(resolve => setTimeout(resolve, ms));
14
+ return new Promise((resolve) => setTimeout(resolve, ms));
15
15
  }
16
16
  exports.delay = delay;
17
+ exports.DefaultFetchConfig = {
18
+ retries: 3,
19
+ timeout: 1000,
20
+ };
21
+ async function proxyFetchRetries(fetch, config = exports.DefaultFetchConfig) {
22
+ let lastError = null;
23
+ for (let attempt = 0; attempt <= config.retries; attempt++) {
24
+ try {
25
+ const timeoutPromise = new Promise((_, reject) => {
26
+ setTimeout(() => reject(new Error('Request timeout')), config.timeout);
27
+ });
28
+ return await Promise.race([fetch, timeoutPromise]);
29
+ }
30
+ catch (error) {
31
+ lastError = error instanceof Error ? error : new Error(String(error));
32
+ if (attempt < config.retries) {
33
+ // Exponential backoff: wait 1s, 2s, 4s, etc.
34
+ const delay = Math.pow(2, attempt) * 1000;
35
+ await new Promise((resolve) => setTimeout(resolve, delay));
36
+ }
37
+ }
38
+ }
39
+ throw new Error(`Failed to fetch after ${config.retries + 1} attempts. Last error: ${lastError instanceof Error ? lastError.message : JSON.stringify(lastError, null, 2)}`);
40
+ }
41
+ exports.proxyFetchRetries = proxyFetchRetries;
42
+ function isValidSubaccountId(subaccountId) {
43
+ return (subaccountId << 16) >> 16 === subaccountId && subaccountId !== -0x8000;
44
+ }
45
+ exports.isValidSubaccountId = isValidSubaccountId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evaafi/sdk",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
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": [
@@ -19,7 +19,6 @@
19
19
  "license": "MIT",
20
20
  "homepage": "https://github.com/evaafi/sdk#readme",
21
21
  "devDependencies": {
22
- "@orbs-network/ton-access": "^2.3.3",
23
22
  "@ton/core": "0.56.0",
24
23
  "@ton/crypto": "^3.3.0",
25
24
  "@tonconnect/sdk": "3.0.5",
@@ -38,6 +37,8 @@
38
37
  "crypto-js": ">=4.2.0"
39
38
  },
40
39
  "dependencies": {
40
+ "@pythnetwork/hermes-client": "^2.0.0",
41
+ "@pythnetwork/pyth-ton-js": "^0.1.2",
41
42
  "@ton/ton": "14.0.0",
42
43
  "dotenv": "16.4.5"
43
44
  },
@@ -0,0 +1,90 @@
1
+ import { Dictionary } from '@ton/ton';
2
+ import { Buffer } from 'buffer';
3
+ import { ASSET_ID } from '../constants/assets';
4
+
5
+ export const PYTH_TON_PRICE_FEED_ID = '0x8963217838ab4cf5cadc172203c1f0b763fbaa45f346d8ee50ba994bbcac3026';
6
+ export const PYTH_USDT_PRICE_FEED_ID = '0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b';
7
+ export const PYTH_STTON_PRICE_FEED_ID = '0x9145e059026a4d5a46f3b96408f7e572e33b3257b9c2dbe8dba551c772762002';
8
+ export const PYTH_TSTON_PRICE_FEED_ID = '0x3d1784128eeab5961ec60648fe497d3901eebd211b7f51e4bb0db9f024977d25';
9
+ export const PYTH_USDC_PRICE_FEED_ID = '0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a';
10
+ export const PYTH_USDE_PRICE_FEED_ID = '0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d';
11
+ export const PYTH_TSUSDE_PRICE_FEED_ID = '0xcbe184846426619a60f51056d26efecb0537ad3a73b1e965fe695d06a257cb19';
12
+
13
+ export function bigintToBuffer(value: bigint, size: number): Buffer {
14
+ if (value < 0n) {
15
+ throw new Error('Only non-negative bigint is supported');
16
+ }
17
+ // it's questionable whether it stores in LE or BE
18
+ // and what option will TVM use, now by default it's BE
19
+ const hex = value.toString(16);
20
+ const padded = hex.padStart(size * 2, '0');
21
+ return Buffer.from(padded, 'hex');
22
+ }
23
+
24
+ export const packConnectedFeeds = (evaa_id: bigint, reffered_id: bigint) => {
25
+ return Buffer.concat([bigintToBuffer(evaa_id, 32), bigintToBuffer(reffered_id, 32)]);
26
+ };
27
+
28
+ export const EVAA_TON_PRICE_FEED_ID = ASSET_ID.TON;
29
+ export const EVAA_NOT_PRICE_FEED_ID = ASSET_ID.NOT;
30
+ export const EVAA_DOGS_PRICE_FEED_ID = ASSET_ID.DOGS;
31
+ export const EVAA_USDT_PRICE_FEED_ID = ASSET_ID.USDT;
32
+ export const EVAA_STTON_PRICE_FEED_ID = ASSET_ID.stTON;
33
+ export const EVAA_TSTON_PRICE_FEED_ID = ASSET_ID.tsTON;
34
+ export const EVAA_JUSDC_PRICE_FEED_ID = ASSET_ID.jUSDC;
35
+ export const EVAA_JUSDT_PRICE_FEED_ID = ASSET_ID.jUSDT;
36
+ export const EVAA_USDE_PRICE_FEED_ID = ASSET_ID.USDe;
37
+ export const EVAA_TSUSDE_PRICE_FEED_ID = ASSET_ID.tsUSDe;
38
+
39
+ export const MAIN_POOL_FEEDS_MAP: Dictionary<bigint, Buffer> = (() => {
40
+ const map = Dictionary.empty<bigint, Buffer>();
41
+ map.set(BigInt(PYTH_TON_PRICE_FEED_ID), packConnectedFeeds(EVAA_TON_PRICE_FEED_ID, 0n));
42
+ map.set(BigInt(PYTH_USDT_PRICE_FEED_ID), packConnectedFeeds(EVAA_USDT_PRICE_FEED_ID, 0n));
43
+ map.set(
44
+ BigInt(PYTH_STTON_PRICE_FEED_ID),
45
+ packConnectedFeeds(EVAA_STTON_PRICE_FEED_ID, BigInt(PYTH_TON_PRICE_FEED_ID)),
46
+ );
47
+ map.set(
48
+ BigInt(PYTH_TSTON_PRICE_FEED_ID),
49
+ packConnectedFeeds(EVAA_TSTON_PRICE_FEED_ID, BigInt(PYTH_TON_PRICE_FEED_ID)),
50
+ );
51
+ map.set(BigInt(PYTH_USDC_PRICE_FEED_ID), packConnectedFeeds(EVAA_JUSDC_PRICE_FEED_ID, 0n));
52
+ map.set(BigInt(PYTH_USDT_PRICE_FEED_ID), packConnectedFeeds(EVAA_JUSDT_PRICE_FEED_ID, 0n));
53
+ map.set(BigInt(PYTH_USDE_PRICE_FEED_ID), packConnectedFeeds(EVAA_USDE_PRICE_FEED_ID, 0n));
54
+ map.set(BigInt(PYTH_TSUSDE_PRICE_FEED_ID), packConnectedFeeds(EVAA_TSUSDE_PRICE_FEED_ID, 0n));
55
+ return map;
56
+ })();
57
+
58
+ export type FeedMapItem = {
59
+ evaaId: bigint;
60
+ referredPythFeed: bigint;
61
+ };
62
+
63
+ export function parseFeedsMapDict(dict: Dictionary<bigint, Buffer>) {
64
+ const parsedData = new Map<bigint, FeedMapItem>();
65
+ for (const key of dict.keys()) {
66
+ const buffer = dict.get(key)!;
67
+
68
+ const hex1 = '0x' + buffer.toString('hex', 0, 32);
69
+ const hex2 = '0x' + buffer.toString('hex', 32);
70
+
71
+ const evaaId = BigInt(hex1);
72
+ const referredPythFeed = BigInt(hex2);
73
+
74
+ parsedData.set(key, { evaaId, referredPythFeed });
75
+ }
76
+
77
+ return parsedData;
78
+ }
79
+
80
+ export const TESTNET_ALLOWED_REF_TOKENS: Dictionary<bigint, bigint> = (() => {
81
+ const map = Dictionary.empty<bigint, bigint>();
82
+ map.set(BigInt(EVAA_JUSDT_PRICE_FEED_ID), BigInt(EVAA_USDT_PRICE_FEED_ID));
83
+ return map;
84
+ })();
85
+
86
+ export const TESTNET_FEEDS_MAP: Dictionary<bigint, Buffer> = (() => {
87
+ const map = Dictionary.empty<bigint, Buffer>();
88
+ map.set(BigInt(PYTH_TON_PRICE_FEED_ID), packConnectedFeeds(EVAA_TON_PRICE_FEED_ID, 0n));
89
+ return map;
90
+ })();
@@ -174,7 +174,7 @@ export function calculateLiquidationAmounts(
174
174
 
175
175
  const _isBadDebt = isBadDebt(supplyAmount, borrowAmount, liquidationBonus, masterConstants);
176
176
  if (!_isBadDebt) {
177
- allowedCollateralValue = BigMath.min(allowedCollateralValue, BigMath.max(allowedCollateralValue / 2n, collateralThreshold));
177
+ allowedCollateralValue = BigMath.min(allowedCollateralValue, BigMath.max(allowedCollateralValue / 3n, collateralThreshold));
178
178
  }
179
179
 
180
180
  const loanValue = toAssetWorth(loanInfo.balance, loanInfo.scale, loanInfo.price);
package/src/api/math.ts CHANGED
@@ -452,7 +452,7 @@ export function calculateLiquidationData(
452
452
  const liquidationBonus = collateralAssetConfig.liquidationBonus;
453
453
  const loanScale = 10n ** loanAssetConfig.decimals;
454
454
  values.push(
455
- (bigIntMax(collateralValue / 2n, bigIntMin(collateralValue, COLLATERAL_WORTH_THRESHOLD)) *
455
+ (bigIntMax(collateralValue / 3n, bigIntMin(collateralValue, COLLATERAL_WORTH_THRESHOLD)) *
456
456
  loanScale *
457
457
  poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE) /
458
458
  liquidationBonus /