@evaafi/sdk 0.9.0 → 0.9.2

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 (132) hide show
  1. package/dist/api/feeds.d.ts +16 -24
  2. package/dist/api/feeds.js +22 -49
  3. package/dist/api/math.d.ts +1 -1
  4. package/dist/api/math.js +55 -38
  5. package/dist/api/parser.d.ts +2 -2
  6. package/dist/api/parser.js +3 -3
  7. package/dist/api/parsers/PythOracleParser.d.ts +3 -2
  8. package/dist/api/parsers/PythOracleParser.js +2 -1
  9. package/dist/api/prices.d.ts +1 -0
  10. package/dist/api/prices.js +2 -1
  11. package/dist/constants/assets/assetId.d.ts +3 -1
  12. package/dist/constants/assets/assetId.js +5 -1
  13. package/dist/constants/assets/mainnet.d.ts +2 -0
  14. package/dist/constants/assets/mainnet.js +13 -1
  15. package/dist/constants/general/index.d.ts +25 -11
  16. package/dist/constants/general/index.js +15 -1
  17. package/dist/constants/general/mainnet.d.ts +1 -0
  18. package/dist/constants/general/mainnet.js +2 -1
  19. package/dist/constants/pools/mainnet.d.ts +4 -0
  20. package/dist/constants/pools/mainnet.js +45 -28
  21. package/dist/constants/pools/testnet.js +14 -6
  22. package/dist/contracts/AbstractMaster.d.ts +239 -127
  23. package/dist/contracts/AbstractMaster.js +101 -16
  24. package/dist/contracts/ClassicMaster.d.ts +12 -12
  25. package/dist/contracts/PythMaster.d.ts +41 -24
  26. package/dist/contracts/PythMaster.js +61 -76
  27. package/dist/contracts/PythOracle.d.ts +16 -0
  28. package/dist/contracts/PythOracle.js +19 -0
  29. package/dist/contracts/index.d.ts +1 -0
  30. package/dist/contracts/index.js +1 -0
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/{prices → oracles}/Types.d.ts +1 -4
  34. package/dist/oracles/collectors/AbstractCollector.d.ts +10 -0
  35. package/dist/oracles/collectors/AbstractCollector.js +6 -0
  36. package/dist/oracles/collectors/ClassicCollector.d.ts +22 -0
  37. package/dist/oracles/collectors/ClassicCollector.js +192 -0
  38. package/dist/oracles/collectors/PythCollector.d.ts +27 -0
  39. package/dist/oracles/collectors/PythCollector.js +252 -0
  40. package/dist/oracles/collectors/index.d.ts +3 -0
  41. package/dist/oracles/collectors/index.js +19 -0
  42. package/dist/{prices → oracles}/index.d.ts +2 -3
  43. package/dist/{prices → oracles}/index.js +2 -3
  44. package/dist/oracles/prices/AbstractPrices.d.ts +33 -0
  45. package/dist/oracles/prices/AbstractPrices.js +40 -0
  46. package/dist/oracles/prices/ClassicPrices.d.ts +19 -0
  47. package/dist/oracles/prices/ClassicPrices.js +48 -0
  48. package/dist/oracles/prices/PythPrices.d.ts +18 -0
  49. package/dist/oracles/prices/PythPrices.js +32 -0
  50. package/dist/oracles/prices/index.d.ts +3 -0
  51. package/dist/oracles/prices/index.js +19 -0
  52. package/dist/{prices → oracles}/utils.d.ts +7 -1
  53. package/dist/{prices → oracles}/utils.js +10 -1
  54. package/dist/rewards/RewardMaster.d.ts +1 -0
  55. package/dist/rewards/RewardUser.d.ts +1 -0
  56. package/dist/types/Master.d.ts +5 -5
  57. package/dist/types/MasterRewards.d.ts +1 -0
  58. package/dist/types/UserRewards.d.ts +1 -0
  59. package/dist/utils/fivaUtils.d.ts +2 -0
  60. package/dist/utils/fivaUtils.js +19 -0
  61. package/dist/utils/sha256BigInt.d.ts +1 -0
  62. package/dist/utils/userJettonWallet.js +15 -1
  63. package/package.json +2 -3
  64. package/src/api/feeds.ts +24 -60
  65. package/src/api/math.ts +118 -90
  66. package/src/api/parser.ts +5 -5
  67. package/src/api/parsers/PythOracleParser.ts +6 -2
  68. package/src/api/prices.ts +2 -1
  69. package/src/constants/assets/assetId.ts +7 -1
  70. package/src/constants/assets/mainnet.ts +24 -0
  71. package/src/constants/general/index.ts +16 -1
  72. package/src/constants/general/mainnet.ts +1 -0
  73. package/src/constants/pools/mainnet.ts +42 -38
  74. package/src/constants/pools/testnet.ts +17 -8
  75. package/src/contracts/AbstractMaster.ts +272 -144
  76. package/src/contracts/ClassicMaster.ts +12 -12
  77. package/src/contracts/PythMaster.ts +130 -123
  78. package/src/contracts/PythOracle.ts +20 -0
  79. package/src/contracts/index.ts +2 -0
  80. package/src/index.ts +1 -1
  81. package/src/{prices → oracles}/Types.ts +0 -5
  82. package/src/oracles/collectors/AbstractCollector.ts +22 -0
  83. package/src/oracles/collectors/ClassicCollector.ts +263 -0
  84. package/src/oracles/collectors/PythCollector.ts +358 -0
  85. package/src/oracles/collectors/index.ts +3 -0
  86. package/src/{prices → oracles}/index.ts +2 -3
  87. package/src/oracles/prices/AbstractPrices.ts +59 -0
  88. package/src/oracles/prices/ClassicPrices.ts +52 -0
  89. package/src/oracles/prices/PythPrices.ts +40 -0
  90. package/src/oracles/prices/index.ts +3 -0
  91. package/src/{prices → oracles}/utils.ts +12 -1
  92. package/src/types/Master.ts +4 -6
  93. package/src/utils/fivaUtils.ts +19 -0
  94. package/src/utils/userJettonWallet.ts +18 -1
  95. package/dist/api/pyth.d.ts +0 -16
  96. package/dist/api/pyth.js +0 -35
  97. package/dist/constants/assets.d.ts +0 -48
  98. package/dist/constants/assets.js +0 -176
  99. package/dist/constants/general.d.ts +0 -67
  100. package/dist/constants/general.js +0 -75
  101. package/dist/constants/pools.d.ts +0 -13
  102. package/dist/constants/pools.js +0 -120
  103. package/dist/contracts/MasterContract.d.ts +0 -156
  104. package/dist/contracts/MasterContract.js +0 -260
  105. package/dist/prices/Oracle.interface.d.ts +0 -9
  106. package/dist/prices/Oracle.interface.js +0 -2
  107. package/dist/prices/Prices.d.ts +0 -11
  108. package/dist/prices/Prices.js +0 -53
  109. package/dist/prices/PricesCollector.d.ts +0 -22
  110. package/dist/prices/PricesCollector.js +0 -146
  111. package/dist/prices/PythCollector.d.ts +0 -22
  112. package/dist/prices/PythCollector.js +0 -217
  113. package/src/prices/Oracle.interface.ts +0 -18
  114. package/src/prices/Prices.ts +0 -45
  115. package/src/prices/PricesCollector.ts +0 -169
  116. package/src/prices/PythCollector.ts +0 -294
  117. /package/dist/{prices → oracles}/Types.js +0 -0
  118. /package/dist/{prices → oracles}/constants.d.ts +0 -0
  119. /package/dist/{prices → oracles}/constants.js +0 -0
  120. /package/dist/{prices → oracles}/sources/Backend.d.ts +0 -0
  121. /package/dist/{prices → oracles}/sources/Backend.js +0 -0
  122. /package/dist/{prices → oracles}/sources/Icp.d.ts +0 -0
  123. /package/dist/{prices → oracles}/sources/Icp.js +0 -0
  124. /package/dist/{prices → oracles}/sources/PriceSource.d.ts +0 -0
  125. /package/dist/{prices → oracles}/sources/PriceSource.js +0 -0
  126. /package/dist/{prices → oracles}/sources/index.d.ts +0 -0
  127. /package/dist/{prices → oracles}/sources/index.js +0 -0
  128. /package/src/{prices → oracles}/constants.ts +0 -0
  129. /package/src/{prices → oracles}/sources/Backend.ts +0 -0
  130. /package/src/{prices → oracles}/sources/Icp.ts +0 -0
  131. /package/src/{prices → oracles}/sources/PriceSource.ts +0 -0
  132. /package/src/{prices → oracles}/sources/index.ts +0 -0
@@ -1,294 +0,0 @@
1
- import { HermesClient, HexString, PriceUpdate } from '@pythnetwork/hermes-client';
2
- import { Cell, Dictionary } from '@ton/core';
3
- import { checkNotInDebtAtAll } from '../api/math';
4
- import { OracleConfig } from '../api/parsers/PythOracleParser';
5
- import { packPythUpdatesData } from '../api/prices';
6
- import { STTON_MAINNET, TON_MAINNET, TSTON_MAINNET, TSUSDE_MAINNET, USDE_MAINNET } from '../constants';
7
- import { FeedMapItem, parseFeedsMapDict, PoolAssetConfig, PoolAssetsConfig } from '../types/Master';
8
- import { FetchConfig, proxyFetchRetries } from '../utils/utils';
9
- import { Oracle } from './Oracle.interface';
10
- import { Prices } from './Prices';
11
- import { PythFeedUpdateType, PythPriceSourcesConfig } from './Types';
12
- import { TTL_ORACLE_DATA_SEC } from './constants';
13
-
14
- export type PythCollectorConfig = {
15
- poolAssetsConfig: PoolAssetsConfig;
16
- pythOracle: OracleConfig;
17
- pythConfig: PythPriceSourcesConfig;
18
- };
19
-
20
- export class PythCollector implements Oracle {
21
- #oracleInfo: OracleConfig;
22
- #parsedFeedsMap: Map<bigint, FeedMapItem>;
23
- #pythConfig: PythPriceSourcesConfig;
24
- #poolAssetsConfig: PoolAssetsConfig;
25
-
26
- #pythToEvaaDirect = new Map<bigint, bigint>(); // pythId -> evaaId (native)
27
- #pythToEvaaReferred = new Map<bigint, Set<bigint>>(); // pythId -> Set<evaaId>,
28
- #evaaToPythDirect = new Map<bigint, bigint>(); // evaaId -> pythId (native)
29
- #allowedRefEvaa = new Map<bigint, bigint>(); // evaaId -> baseEvaaId (allowedRefTokens)
30
-
31
- constructor(config: PythCollectorConfig) {
32
- this.#oracleInfo = config.pythOracle;
33
- this.#pythConfig = config.pythConfig;
34
- this.#poolAssetsConfig = config.poolAssetsConfig;
35
- this.#parsedFeedsMap = parseFeedsMapDict(this.#oracleInfo.feedsMap);
36
-
37
- // 1) pythId -> evaaId, evaaId -> pythId
38
- for (const [pythId, feedInfo] of this.#parsedFeedsMap.entries()) {
39
- this.#pythToEvaaDirect.set(pythId, feedInfo.evaaId);
40
- this.#evaaToPythDirect.set(feedInfo.evaaId, pythId);
41
- }
42
-
43
- // 2) pythId (native) -> Set<evaaId>
44
- for (const [pythId, feedInfo] of this.#parsedFeedsMap.entries()) {
45
- const ref = feedInfo.referredPythFeed;
46
- if (ref && ref !== 0n) {
47
- if (!this.#pythToEvaaReferred.has(ref)) this.#pythToEvaaReferred.set(ref, new Set());
48
- this.#pythToEvaaReferred.get(ref)!.add(feedInfo.evaaId);
49
- }
50
- }
51
-
52
- // 3) evaaId -> baseEvaaId (allowedRefTokens)
53
- for (const evaaId of this.#oracleInfo.allowedRefTokens.keys()) {
54
- const base = this.#oracleInfo.allowedRefTokens.get(evaaId)!;
55
- this.#allowedRefEvaa.set(evaaId, base);
56
-
57
- // If baseEvaaId have pythId. evaaId -> pyth(base)
58
- const basePyth = this.#evaaToPythDirect.get(base);
59
- if (basePyth) {
60
- if (!this.#pythToEvaaReferred.has(basePyth)) this.#pythToEvaaReferred.set(basePyth, new Set());
61
- this.#pythToEvaaReferred.get(basePyth)!.add(evaaId);
62
- }
63
- }
64
- }
65
-
66
- async getPricesForLiquidate(
67
- realPrincipals: Dictionary<bigint, bigint>,
68
- fetchConfig?: FetchConfig,
69
- ): Promise<Prices> {
70
- const assets = this.#filterEmptyPrincipalsAndAssets(realPrincipals);
71
- if (assets.includes(undefined)) {
72
- throw new Error('User from another pool');
73
- }
74
- return await this.getPrices(
75
- assets.map((x) => x!),
76
- fetchConfig,
77
- );
78
- }
79
-
80
- async getPricesForSupplyWithdraw(
81
- realPrincipals: Dictionary<bigint, bigint>,
82
- supplyAsset: PoolAssetConfig | undefined,
83
- withdrawAsset: PoolAssetConfig | undefined,
84
- collateralToDebt: boolean,
85
- fetchConfig?: FetchConfig,
86
- ): Promise<Prices> {
87
- let assets = this.#filterEmptyPrincipalsAndAssets(realPrincipals);
88
- if (
89
- checkNotInDebtAtAll(realPrincipals) &&
90
- withdrawAsset &&
91
- (realPrincipals.get(withdrawAsset.assetId) ?? 0n) > 0n &&
92
- !collateralToDebt
93
- ) {
94
- return new Prices(Dictionary.empty<bigint, bigint>(), Cell.EMPTY, undefined, undefined);
95
- }
96
- if (assets.includes(undefined)) {
97
- throw new Error('User from another pool');
98
- }
99
- if (withdrawAsset && !assets.find((a) => a?.assetId === withdrawAsset.assetId)) {
100
- assets.push(withdrawAsset);
101
- }
102
- if (collateralToDebt && assets.length == 1) {
103
- throw new Error('Cannot debt only one supplied asset');
104
- }
105
- return await this.getPrices(
106
- assets.map((x) => x!),
107
- fetchConfig,
108
- );
109
- }
110
-
111
- async getPrices(assets: PoolAssetsConfig = this.#poolAssetsConfig, fetchConfig?: FetchConfig): Promise<Prices> {
112
- // Declare variables at the beginning
113
- let minPublishTime: bigint | undefined;
114
- let maxPublishTime: bigint | undefined;
115
-
116
- if (assets.length === 0) {
117
- return new Prices(Dictionary.empty<bigint, bigint>(), Cell.EMPTY, undefined, undefined);
118
- }
119
-
120
- const requiredFeeds = this.createRequiredFeedsList(assets.map((a) => a.assetId));
121
- const pythUpdates = await this.#fetchPythUpdatesWithRetry(requiredFeeds, fetchConfig);
122
-
123
- // Calculate min and max publish times for validation
124
-
125
- if (pythUpdates.parsed && pythUpdates.parsed.length > 0) {
126
- const publishTimes = pythUpdates.parsed.map((u) => BigInt(u.price.publish_time));
127
- const tmin = publishTimes.reduce((a, b) => (a < b ? a : b));
128
- const tmax = publishTimes.reduce((a, b) => (a > b ? a : b));
129
-
130
- if (tmax - tmin > TTL_ORACLE_DATA_SEC) {
131
- throw new Error(
132
- `Price feeds don't fit in a single 3-minute window. Time span: ${tmax - tmin} seconds (max allowed: ${TTL_ORACLE_DATA_SEC})`,
133
- );
134
- }
135
-
136
- // Set boundaries using "from oldest" approach: minPublishTime = tmin, maxPublishTime = tmin + 180
137
- minPublishTime = tmin;
138
- maxPublishTime = tmin + BigInt(TTL_ORACLE_DATA_SEC);
139
- }
140
-
141
- const pricesDict = Dictionary.empty<bigint, bigint>();
142
- const pythPriceUpdates = pythUpdates.parsed;
143
-
144
- if (pythPriceUpdates) {
145
- // Only set prices for requested assets, not all possible mapped assets
146
- const requestedAssetIds = new Set(assets.map((a) => a.assetId));
147
-
148
- for (const u of pythPriceUpdates) {
149
- const pythId = BigInt('0x' + u.id);
150
-
151
- const price = (BigInt(u.price.price) * BigInt(10 ** 9)) / BigInt(10 ** (u.price.expo * -1));
152
-
153
- // Set price for direct mapping if the evaaId is requested
154
- const directEvaa = this.#pythToEvaaDirect.get(pythId);
155
- if (directEvaa && requestedAssetIds.has(directEvaa)) {
156
- pricesDict.set(directEvaa, price);
157
- }
158
-
159
- // Set price for referred assets only if they are requested
160
- const referredSet = this.#pythToEvaaReferred.get(pythId);
161
- if (referredSet && referredSet.size) {
162
- for (const evaaId of referredSet) {
163
- if (requestedAssetIds.has(evaaId)) {
164
- pricesDict.set(evaaId, price);
165
- }
166
- }
167
- }
168
- }
169
-
170
- // TODO: fix it
171
-
172
- if (pricesDict.get(TSTON_MAINNET.assetId) && pricesDict.get(TON_MAINNET.assetId)) {
173
- pricesDict.set(
174
- TSTON_MAINNET.assetId,
175
- (pricesDict.get(TSTON_MAINNET.assetId)! * pricesDict.get(TON_MAINNET.assetId)!) / BigInt(10 ** 9),
176
- );
177
- }
178
-
179
- // TODO: fix it
180
- if (pricesDict.get(STTON_MAINNET.assetId) && pricesDict.get(TON_MAINNET.assetId)) {
181
- pricesDict.set(
182
- STTON_MAINNET.assetId,
183
- (pricesDict.get(STTON_MAINNET.assetId)! * pricesDict.get(TON_MAINNET.assetId)!) / BigInt(10 ** 9),
184
- );
185
- }
186
-
187
- // TODO: fix it
188
- if (pricesDict.get(TSUSDE_MAINNET.assetId) && pricesDict.get(USDE_MAINNET.assetId)) {
189
- pricesDict.set(
190
- TSUSDE_MAINNET.assetId,
191
- (pricesDict.get(TSUSDE_MAINNET.assetId)! * pricesDict.get(USDE_MAINNET.assetId)!) / BigInt(10 ** 9),
192
- );
193
- }
194
-
195
- // Check that all requested assets have prices
196
- const missing = assets.map((a) => a.assetId).filter((id) => pricesDict.get(id) === undefined);
197
-
198
- if (missing.length) {
199
- throw new Error(
200
- `Missing prices for ${missing.length} asset(s): ${missing.map((x) => x.toString()).join(', ')}`,
201
- );
202
- }
203
-
204
- const dataCell = packPythUpdatesData(pythUpdates.binary);
205
- return new Prices(pricesDict, dataCell, minPublishTime, maxPublishTime);
206
- }
207
- return new Prices(Dictionary.empty<bigint, bigint>(), Cell.EMPTY, minPublishTime, maxPublishTime);
208
- }
209
-
210
- async getPricesForWithdraw(
211
- realPrincipals: Dictionary<bigint, bigint>,
212
- withdrawAsset: PoolAssetConfig,
213
- collateralToDebt = false,
214
- fetchConfig?: FetchConfig,
215
- ): Promise<Prices> {
216
- let assets = this.#filterEmptyPrincipalsAndAssets(realPrincipals);
217
- if (
218
- checkNotInDebtAtAll(realPrincipals) &&
219
- (realPrincipals.get(withdrawAsset.assetId) ?? 0n) > 0n &&
220
- !collateralToDebt
221
- ) {
222
- return new Prices(Dictionary.empty<bigint, bigint>(), Cell.EMPTY);
223
- }
224
- if (assets.includes(undefined)) {
225
- throw new Error('User from another pool');
226
- }
227
- if (!assets.includes(withdrawAsset)) {
228
- assets.push(withdrawAsset);
229
- }
230
- if (collateralToDebt && assets.length == 1) {
231
- throw new Error('Cannot debt only one supplied asset');
232
- }
233
- return await this.getPrices(
234
- assets.map((x) => x!),
235
- fetchConfig,
236
- );
237
- }
238
-
239
- /**
240
- * Updates feeds data from specified endpoint
241
- * @param feedIds list of pyth feed ids to fetch
242
- * @returns binary - buffer of feeds update, parsed - json feeds data
243
- */
244
- async #getPythFeedsUpdates(feedIds: HexString[]): Promise<PythFeedUpdateType> {
245
- const latestPriceUpdates: PriceUpdate = await Promise.any(
246
- this.#pythConfig.pythEndpoints.map((x) =>
247
- new HermesClient(x).getLatestPriceUpdates(feedIds, { encoding: 'hex' }),
248
- ),
249
- );
250
-
251
- const parsed = latestPriceUpdates['parsed'];
252
- const binary = Buffer.from(latestPriceUpdates.binary.data[0], 'hex');
253
-
254
- return { binary, parsed };
255
- }
256
-
257
- async #fetchPythUpdatesWithRetry(
258
- requiredFeeds: HexString[],
259
- fetchConfig?: FetchConfig,
260
- ): Promise<PythFeedUpdateType> {
261
- return proxyFetchRetries(this.#getPythFeedsUpdates(requiredFeeds), fetchConfig);
262
- }
263
-
264
- public createRequiredFeedsList(evaaIds: bigint[]): HexString[] {
265
- const requiredFeeds = new Set<bigint>();
266
-
267
- for (const evaaId of evaaIds) {
268
- let pythId = this.#evaaToPythDirect.get(evaaId);
269
-
270
- // If evaaId no have native feed — try by allowedRefTokens (evAA->baseEvAA->pyth)
271
- if (!pythId) {
272
- const baseEvaa = this.#allowedRefEvaa.get(evaaId);
273
- if (baseEvaa) pythId = this.#evaaToPythDirect.get(baseEvaa) ?? null!;
274
- }
275
-
276
- if (pythId) {
277
- requiredFeeds.add(pythId);
278
- const feedInfo = this.#parsedFeedsMap.get(pythId);
279
- if (feedInfo?.referredPythFeed && feedInfo.referredPythFeed !== 0n) {
280
- requiredFeeds.add(feedInfo.referredPythFeed);
281
- }
282
- }
283
- }
284
-
285
- return Array.from(requiredFeeds).map((id) => '0x' + id.toString(16));
286
- }
287
-
288
- #filterEmptyPrincipalsAndAssets(principals: Dictionary<bigint, bigint>) {
289
- return principals
290
- .keys()
291
- .filter((x) => principals.get(x)! != 0n)
292
- .map((x) => this.#poolAssetsConfig.find((asset) => asset.assetId == x));
293
- }
294
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes