zo-sdk 0.1.21 → 0.1.23

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 (94) hide show
  1. package/dist/abstract/BaseDataAPI.d.cts +2 -2
  2. package/dist/abstract/BaseDataAPI.d.cts.map +1 -1
  3. package/dist/abstract/BaseDataAPI.d.mts +2 -2
  4. package/dist/abstract/BaseDataAPI.d.mts.map +1 -1
  5. package/dist/consts/deployments-zbtcvc-mainnet.json +180 -0
  6. package/dist/consts/index.cjs +27 -20
  7. package/dist/consts/index.cjs.map +1 -1
  8. package/dist/consts/index.d.cts +5 -17
  9. package/dist/consts/index.d.cts.map +1 -1
  10. package/dist/consts/index.d.mts +5 -17
  11. package/dist/consts/index.d.mts.map +1 -1
  12. package/dist/consts/index.mjs +26 -19
  13. package/dist/consts/index.mjs.map +1 -1
  14. package/dist/factory/SDKFactory.cjs +36 -0
  15. package/dist/factory/SDKFactory.cjs.map +1 -1
  16. package/dist/factory/SDKFactory.d.cts +11 -1
  17. package/dist/factory/SDKFactory.d.cts.map +1 -1
  18. package/dist/factory/SDKFactory.d.mts +11 -1
  19. package/dist/factory/SDKFactory.d.mts.map +1 -1
  20. package/dist/factory/SDKFactory.mjs +36 -0
  21. package/dist/factory/SDKFactory.mjs.map +1 -1
  22. package/dist/implementations/SLPDataAPI.cjs +54 -32
  23. package/dist/implementations/SLPDataAPI.cjs.map +1 -1
  24. package/dist/implementations/SLPDataAPI.d.cts +2 -2
  25. package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
  26. package/dist/implementations/SLPDataAPI.d.mts +2 -2
  27. package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
  28. package/dist/implementations/SLPDataAPI.mjs +54 -32
  29. package/dist/implementations/SLPDataAPI.mjs.map +1 -1
  30. package/dist/implementations/USDZAPI.cjs +1 -1
  31. package/dist/implementations/USDZAPI.cjs.map +1 -1
  32. package/dist/implementations/USDZAPI.d.cts +1 -1
  33. package/dist/implementations/USDZAPI.d.cts.map +1 -1
  34. package/dist/implementations/USDZAPI.d.mts +1 -1
  35. package/dist/implementations/USDZAPI.d.mts.map +1 -1
  36. package/dist/implementations/USDZAPI.mjs +1 -1
  37. package/dist/implementations/USDZAPI.mjs.map +1 -1
  38. package/dist/implementations/ZBTCVCAPI.cjs +984 -0
  39. package/dist/implementations/ZBTCVCAPI.cjs.map +1 -0
  40. package/dist/implementations/ZBTCVCAPI.d.cts +133 -0
  41. package/dist/implementations/ZBTCVCAPI.d.cts.map +1 -0
  42. package/dist/implementations/ZBTCVCAPI.d.mts +133 -0
  43. package/dist/implementations/ZBTCVCAPI.d.mts.map +1 -0
  44. package/dist/implementations/ZBTCVCAPI.mjs +980 -0
  45. package/dist/implementations/ZBTCVCAPI.mjs.map +1 -0
  46. package/dist/implementations/ZBTCVCDataAPI.cjs +824 -0
  47. package/dist/implementations/ZBTCVCDataAPI.cjs.map +1 -0
  48. package/dist/implementations/ZBTCVCDataAPI.d.cts +94 -0
  49. package/dist/implementations/ZBTCVCDataAPI.d.cts.map +1 -0
  50. package/dist/implementations/ZBTCVCDataAPI.d.mts +94 -0
  51. package/dist/implementations/ZBTCVCDataAPI.d.mts.map +1 -0
  52. package/dist/implementations/ZBTCVCDataAPI.mjs +820 -0
  53. package/dist/implementations/ZBTCVCDataAPI.mjs.map +1 -0
  54. package/dist/implementations/index.cjs +5 -1
  55. package/dist/implementations/index.cjs.map +1 -1
  56. package/dist/implementations/index.d.cts +2 -0
  57. package/dist/implementations/index.d.cts.map +1 -1
  58. package/dist/implementations/index.d.mts +2 -0
  59. package/dist/implementations/index.d.mts.map +1 -1
  60. package/dist/implementations/index.mjs +2 -0
  61. package/dist/implementations/index.mjs.map +1 -1
  62. package/dist/interfaces/base.d.cts +2 -2
  63. package/dist/interfaces/base.d.cts.map +1 -1
  64. package/dist/interfaces/base.d.mts +2 -2
  65. package/dist/interfaces/base.d.mts.map +1 -1
  66. package/dist/interfaces/index.cjs +2 -0
  67. package/dist/interfaces/index.cjs.map +1 -1
  68. package/dist/interfaces/index.d.cts +2 -0
  69. package/dist/interfaces/index.d.cts.map +1 -1
  70. package/dist/interfaces/index.d.mts +2 -0
  71. package/dist/interfaces/index.d.mts.map +1 -1
  72. package/dist/interfaces/index.mjs +2 -0
  73. package/dist/interfaces/index.mjs.map +1 -1
  74. package/dist/interfaces/zbtcvc.cjs +7 -0
  75. package/dist/interfaces/zbtcvc.cjs.map +1 -0
  76. package/dist/interfaces/zbtcvc.d.cts +64 -0
  77. package/dist/interfaces/zbtcvc.d.cts.map +1 -0
  78. package/dist/interfaces/zbtcvc.d.mts +64 -0
  79. package/dist/interfaces/zbtcvc.d.mts.map +1 -0
  80. package/dist/interfaces/zbtcvc.mjs +6 -0
  81. package/dist/interfaces/zbtcvc.mjs.map +1 -0
  82. package/package.json +8 -8
  83. package/src/abstract/BaseDataAPI.ts +2 -2
  84. package/src/consts/deployments-zbtcvc-mainnet.json +180 -0
  85. package/src/consts/index.ts +28 -35
  86. package/src/factory/SDKFactory.ts +50 -0
  87. package/src/implementations/SLPDataAPI.ts +71 -41
  88. package/src/implementations/USDZAPI.ts +1 -1
  89. package/src/implementations/ZBTCVCAPI.ts +1453 -0
  90. package/src/implementations/ZBTCVCDataAPI.ts +985 -0
  91. package/src/implementations/index.ts +2 -0
  92. package/src/interfaces/base.ts +2 -2
  93. package/src/interfaces/index.ts +8 -0
  94. package/src/interfaces/zbtcvc.ts +115 -0
@@ -0,0 +1,824 @@
1
+ "use strict";
2
+ /* eslint-disable no-await-in-loop */
3
+ /**
4
+ * ZBTCVC DataAPI implementation
5
+ * Implements ZBTCVC-specific data access methods
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.ZBTCVCDataAPI = void 0;
9
+ const utils_1 = require("@mysten/sui/utils");
10
+ const abstract_1 = require("../abstract/index.cjs");
11
+ const consts_1 = require("../consts/index.cjs");
12
+ const utils_2 = require("../utils.cjs");
13
+ class ZBTCVCDataAPI extends abstract_1.BaseDataAPI {
14
+ constructor(network, provider, apiEndpoint, connectionURL) {
15
+ super(network, provider, apiEndpoint, connectionURL, consts_1.LPToken.ZBTCVC);
16
+ }
17
+ async getStaked(owner) {
18
+ let rawCredentialsData = [];
19
+ let queryNextPage = true;
20
+ let queryCursor;
21
+ const limit = 50;
22
+ while (queryNextPage) {
23
+ const { data, hasNextPage, nextCursor } = await this.provider.getOwnedObjects({
24
+ owner,
25
+ filter: {
26
+ MoveModule: {
27
+ package: this.consts.zoStaking.package,
28
+ module: 'pool',
29
+ },
30
+ },
31
+ options: {
32
+ showType: true,
33
+ showContent: true,
34
+ },
35
+ cursor: queryCursor,
36
+ limit,
37
+ });
38
+ queryNextPage = hasNextPage;
39
+ queryCursor = nextCursor;
40
+ if (!data)
41
+ break;
42
+ rawCredentialsData = [...rawCredentialsData, ...data];
43
+ }
44
+ const pool = await this.getStakePool();
45
+ const credentials = rawCredentialsData.map((item) => ZBTCVCDataAPI.parseCredential(item, pool));
46
+ return {
47
+ credentials,
48
+ amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
49
+ claimable: credentials.reduce((acc, cur) => acc + cur.claimable, BigInt(0)),
50
+ };
51
+ }
52
+ async getStakePool() {
53
+ const raw = await this.provider.getObject({
54
+ id: this.consts.zoStaking.pools[0],
55
+ options: {
56
+ showContent: true,
57
+ },
58
+ });
59
+ return ZBTCVCDataAPI.parseStakePool(raw);
60
+ }
61
+ /**
62
+ * Creates vaults valuation for ZBTCVC
63
+ */
64
+ valuateVaults(tx) {
65
+ const vaultsValuation = tx.moveCall({
66
+ target: `${this.consts.zoCore.upgradedPackage}::market::create_vaults_valuation`,
67
+ typeArguments: [`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`],
68
+ arguments: [
69
+ tx.object(utils_1.SUI_CLOCK_OBJECT_ID),
70
+ tx.object(this.consts.zoCore.market),
71
+ ],
72
+ });
73
+ for (const key of Object.keys(this.consts.zoCore.vaults)) {
74
+ const vault = this.consts.zoCore.vaults[key];
75
+ tx.moveCall({
76
+ target: `${this.consts.zoCore.upgradedPackage}::market::valuate_vault`,
77
+ typeArguments: [
78
+ `${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
79
+ this.consts.coins[key].module,
80
+ ],
81
+ arguments: [
82
+ tx.object(this.consts.zoCore.market),
83
+ tx.object(vault.reservingFeeModel),
84
+ tx.object(this.consts.pythFeeder.feeder[key]),
85
+ vaultsValuation,
86
+ ],
87
+ });
88
+ }
89
+ return vaultsValuation;
90
+ }
91
+ /**
92
+ * Creates symbols valuation for ZBTCVC
93
+ */
94
+ valuateSymbols(tx) {
95
+ const symbolsValuation = tx.moveCall({
96
+ target: `${this.consts.zoCore.upgradedPackage}::market::create_symbols_valuation`,
97
+ typeArguments: [`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`],
98
+ arguments: [
99
+ tx.object(utils_1.SUI_CLOCK_OBJECT_ID),
100
+ tx.object(this.consts.zoCore.market),
101
+ ],
102
+ });
103
+ for (const key of Object.keys(this.consts.zoCore.symbols)) {
104
+ const [direction, token] = (0, utils_2.parseSymbolKey)(key);
105
+ const symbol = this.consts.zoCore.symbols[key];
106
+ tx.moveCall({
107
+ target: `${this.consts.zoCore.upgradedPackage}::market::valuate_symbol`,
108
+ typeArguments: [
109
+ `${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
110
+ this.consts.coins[token].module,
111
+ `${this.consts.zoCore.package}::market::${direction.toUpperCase()}`,
112
+ ],
113
+ arguments: [
114
+ tx.object(this.consts.zoCore.market),
115
+ tx.object(symbol.fundingFeeModel),
116
+ tx.object(this.consts.pythFeeder.feeder[token]),
117
+ symbolsValuation,
118
+ ],
119
+ });
120
+ }
121
+ return symbolsValuation;
122
+ }
123
+ /**
124
+ * Creates both vaults and symbols valuation
125
+ */
126
+ valuate(tx) {
127
+ const vaultsValuation = this.valuateVaults(tx);
128
+ const symbolsValuation = this.valuateSymbols(tx);
129
+ return { vaultsValuation, symbolsValuation };
130
+ }
131
+ /**
132
+ * Valuates the ZBTCVC market
133
+ */
134
+ async valuateMarket() {
135
+ const marketInfo = await this.getMarketInfo();
136
+ const days = 7;
137
+ const fee = await this.getPastFee(days);
138
+ let zbtcvcPrice = 0;
139
+ let value = 0;
140
+ const vaultPromises = Object.keys(this.consts.zoCore.vaults).map(async (vault) => {
141
+ const vaultInfo = await this.getVaultInfo(vault);
142
+ const reservingFeeDelta = ZBTCVCDataAPI.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
143
+ return (reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount) * (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked() / (10 ** this.consts.coins[vault].decimals);
144
+ });
145
+ const symbolPromises = Object.keys(this.consts.zoCore.symbols).map(async (symbol) => {
146
+ const [direction, tokenId] = (0, utils_2.parseSymbolKey)(symbol);
147
+ const symbolInfo = await this.getSymbolInfo(tokenId, direction === 'long');
148
+ const deltaSize = ZBTCVCDataAPI.calcDeltaSize(symbolInfo, (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked());
149
+ const fundingFeeDelta = ZBTCVCDataAPI.calculateSymbolFundingFee(symbolInfo, symbolInfo.fundingFeeModel, (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked(), marketInfo.lpSupplyWithDecimals, Date.now() / 1000);
150
+ return fundingFeeDelta + deltaSize;
151
+ });
152
+ const [vaultValues, symbolValues] = await Promise.all([Promise.all(vaultPromises), Promise.all(symbolPromises)]);
153
+ value = vaultValues.reduce((acc, curr) => acc + curr, 0);
154
+ value += symbolValues.reduce((acc, curr) => acc + curr, 0);
155
+ zbtcvcPrice = value / marketInfo.lpSupplyWithDecimals;
156
+ return {
157
+ marketCap: value,
158
+ price: zbtcvcPrice,
159
+ supply: marketInfo.lpSupplyWithDecimals,
160
+ apr: (fee / value) * 365 / days,
161
+ };
162
+ }
163
+ /**
164
+ * Gets ZBTCVC market information
165
+ */
166
+ async getMarketInfo() {
167
+ this.validateCache();
168
+ if (this.marketInfoCache) {
169
+ return this.marketInfoCache;
170
+ }
171
+ const rawData = await this.provider.getObject({
172
+ id: this.consts.zoCore.market,
173
+ options: {
174
+ showContent: true,
175
+ },
176
+ });
177
+ return ZBTCVCDataAPI.parseMarketInfo(rawData);
178
+ }
179
+ /**
180
+ * Gets ZBTCVC vault information
181
+ */
182
+ async getVaultInfo(vaultToken) {
183
+ this.validateCache();
184
+ if (this.vaultInfoCache[vaultToken]) {
185
+ return this.vaultInfoCache[vaultToken];
186
+ }
187
+ const rawData = await this.provider.getDynamicFieldObject({
188
+ parentId: this.consts.zoCore.vaultsParent,
189
+ name: {
190
+ type: `${this.consts.zoCore.package}::market::VaultName<${this.consts.coins[vaultToken].module}>`,
191
+ value: { dummy_field: false },
192
+ },
193
+ });
194
+ return await this.parseVaultInfo(rawData);
195
+ }
196
+ /**
197
+ * Gets ZBTCVC symbol information
198
+ */
199
+ async getSymbolInfo(indexToken, long) {
200
+ this.validateCache();
201
+ const symbol = (0, utils_2.joinSymbol)(long ? 'long' : 'short', indexToken);
202
+ if (this.symbolInfoCache[symbol]) {
203
+ return this.symbolInfoCache[symbol];
204
+ }
205
+ const rawData = await this.provider.getDynamicFieldObject({
206
+ parentId: this.consts.zoCore.symbolsParent,
207
+ name: {
208
+ type: `${this.consts.zoCore.package}::market::SymbolName<${this.consts.coins[indexToken].module}, ${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}>`,
209
+ value: { dummy_field: false },
210
+ },
211
+ });
212
+ return await this.parseSymbolInfo(rawData, long);
213
+ }
214
+ async getPositionConfig(indexToken, long) {
215
+ this.validateCache();
216
+ const symbol = (0, utils_2.joinSymbol)(long ? 'long' : 'short', indexToken);
217
+ if (this.positionConfigCache[symbol]) {
218
+ return this.positionConfigCache[symbol];
219
+ }
220
+ const rawData = await this.provider.getObject({
221
+ id: this.consts.zoCore.symbols[symbol].positionConfig,
222
+ options: {
223
+ showContent: true,
224
+ },
225
+ });
226
+ return ZBTCVCDataAPI.parsePositionConfig(rawData);
227
+ }
228
+ /**
229
+ * Gets ZBTCVC symbol configuration
230
+ */
231
+ async getSymbolConfig(indexToken, long) {
232
+ this.validateCache();
233
+ try {
234
+ const rawData = await this.provider.getDynamicFieldObject({
235
+ parentId: this.consts.zoCore.market,
236
+ name: {
237
+ type: `${this.consts.zoCore.package}::market::SymbolName<${this.consts.coins[indexToken].module}, ${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}>`,
238
+ value: { dummy_field: false },
239
+ },
240
+ });
241
+ return ZBTCVCDataAPI.parseSymbolConfig(rawData);
242
+ }
243
+ catch {
244
+ // If the dynamic field doesn't exist, return null
245
+ console.error('Symbol Config Not Found');
246
+ return null;
247
+ }
248
+ }
249
+ async getPositionCapInfoList(owner) {
250
+ const positionCapInfoList = [];
251
+ let cursor;
252
+ let hasNextPage = true;
253
+ while (hasNextPage) {
254
+ const positionCaps = await this.provider.getOwnedObjects({
255
+ owner,
256
+ filter: {
257
+ MoveModule: {
258
+ package: this.consts.zoCore.package,
259
+ module: 'market',
260
+ },
261
+ },
262
+ options: {
263
+ showType: true,
264
+ },
265
+ cursor,
266
+ });
267
+ for (const positionCap of positionCaps.data) {
268
+ if (positionCap.data?.type?.includes('PositionCap')) {
269
+ positionCapInfoList.push({
270
+ positionCapId: positionCap.data.objectId,
271
+ symbol0: positionCap.data.type.split('<')[1].split(',')[0].trim(),
272
+ symbol1: positionCap.data.type.split('<')[1].split(',')[1].split(',')[0].trim(),
273
+ long: positionCap.data.type.includes('LONG'),
274
+ });
275
+ }
276
+ }
277
+ // If we don't want to fetch all pages or there are no more pages, break the loop
278
+ hasNextPage = positionCaps.hasNextPage;
279
+ cursor = positionCaps.nextCursor;
280
+ }
281
+ return positionCapInfoList;
282
+ }
283
+ async getPositionInfoList(positionCapInfoList, owner, batchSize = 10) {
284
+ const positionInfoList = [];
285
+ // Process in batches of 10
286
+ for (let i = 0; i < positionCapInfoList.length; i += batchSize) {
287
+ const batch = positionCapInfoList.slice(i, i + batchSize);
288
+ await Promise.all(batch.map(async (positionCapInfo) => {
289
+ try {
290
+ const positionRaw = await this.provider.getDynamicFieldObject({
291
+ parentId: this.consts.zoCore.positionsParent,
292
+ name: {
293
+ type: `${this.consts.zoCore.package}::market::PositionName<${positionCapInfo.symbol0}, ${positionCapInfo.symbol1}, ${this.consts.zoCore.package}::market::${positionCapInfo.long ? 'LONG' : 'SHORT'}>`,
294
+ value: {
295
+ owner,
296
+ id: positionCapInfo.positionCapId,
297
+ },
298
+ },
299
+ });
300
+ positionInfoList.push(await this.parsePositionInfo(positionRaw, positionCapInfo.positionCapId));
301
+ }
302
+ catch (error) {
303
+ // Position might have been deleted after force settlement
304
+ console.warn(`Failed to parse position info for position cap ID ${positionCapInfo.positionCapId}: ${error}`);
305
+ // Continue with next position without adding this one to the list
306
+ }
307
+ }));
308
+ }
309
+ return positionInfoList.sort((a, b) => a.openTimestamp > b.openTimestamp ? 1 : -1);
310
+ }
311
+ async getOpenPositions() {
312
+ let positionDynamicFields = [];
313
+ let _continue = true;
314
+ let cursor;
315
+ while (_continue) {
316
+ // data here will be a list of dynamic fields containing name and value
317
+ const { data, nextCursor, hasNextPage } = await this.provider.getDynamicFields({
318
+ parentId: this.consts.zoCore.positionsParent,
319
+ cursor,
320
+ });
321
+ positionDynamicFields = positionDynamicFields.concat(data);
322
+ _continue = hasNextPage;
323
+ cursor = nextCursor;
324
+ }
325
+ // then we query by dynamic field names and order by time
326
+ const positionInfoList = [];
327
+ await Promise.all(positionDynamicFields.map(async (positionDynamicField) => {
328
+ const positionRaw = await this.provider.getDynamicFieldObject({
329
+ parentId: this.consts.zoCore.positionsParent,
330
+ name: positionDynamicField.name,
331
+ });
332
+ if (positionRaw?.data?.content) {
333
+ const positionInfo = await this.parsePositionInfo(positionRaw, positionDynamicField.objectId);
334
+ if (positionInfo) {
335
+ positionInfoList.push(positionInfo);
336
+ }
337
+ }
338
+ }));
339
+ return positionInfoList
340
+ .filter(positionInfo => !positionInfo.closed)
341
+ .sort((a, b) => (a.openTimestamp > b.openTimestamp ? 1 : -1));
342
+ }
343
+ async getOrderCapInfoList(owner) {
344
+ const orderCapInfoList = [];
345
+ let cursor;
346
+ let hasNextPage = true;
347
+ while (hasNextPage) {
348
+ const orderCaps = await this.provider.getOwnedObjects({
349
+ owner,
350
+ filter: {
351
+ MoveModule: {
352
+ package: this.consts.zoCore.package,
353
+ module: 'market',
354
+ },
355
+ },
356
+ options: {
357
+ showType: true,
358
+ showContent: true,
359
+ },
360
+ cursor,
361
+ });
362
+ for (const orderCap of orderCaps.data) {
363
+ if (orderCap.data?.type?.includes('OrderCap')) {
364
+ orderCapInfoList.push({
365
+ orderCapId: orderCap.data.objectId,
366
+ symbol0: orderCap.data.type.split('<')[1].split(',')[0].trim(),
367
+ symbol1: orderCap.data.type.split('<')[1].split(',')[1].split(',')[0].trim(),
368
+ long: orderCap.data.type.includes('LONG'),
369
+ positionId: orderCap.data.content?.fields?.position_id,
370
+ });
371
+ }
372
+ }
373
+ hasNextPage = orderCaps.hasNextPage;
374
+ cursor = orderCaps.nextCursor;
375
+ }
376
+ return orderCapInfoList;
377
+ }
378
+ async getOrderInfoList(orderCapInfoList, owner, batchSize = 10) {
379
+ const orderInfoList = [];
380
+ // Process in batches of 10
381
+ for (let i = 0; i < orderCapInfoList.length; i += batchSize) {
382
+ const batch = orderCapInfoList.slice(i, i + batchSize);
383
+ await Promise.all(batch.map(async (orderCapInfo) => {
384
+ try {
385
+ const orderRaw = await this.provider.getDynamicFieldObject({
386
+ parentId: this.consts.zoCore.ordersParent,
387
+ name: {
388
+ // We have enforced collateral coin type to match with fee coin type so we can use symbol0 in the first slot and the last slot of the OrderName
389
+ type: `${this.consts.zoCore.package}::market::OrderName<${orderCapInfo.symbol0}, ${orderCapInfo.symbol1}, ${this.consts.zoCore.package}::market::${orderCapInfo.long ? 'LONG' : 'SHORT'}, ${orderCapInfo.symbol0}>`,
390
+ value: {
391
+ owner,
392
+ id: orderCapInfo.orderCapId,
393
+ position_id: {
394
+ vec: orderCapInfo.positionId ? [orderCapInfo.positionId] : [],
395
+ },
396
+ },
397
+ },
398
+ });
399
+ orderInfoList.push(this.parseOrderInfo(orderRaw, orderCapInfo.orderCapId));
400
+ }
401
+ catch (error) {
402
+ // Order might have been deleted
403
+ console.warn(`Failed to parse order info for order cap ID ${orderCapInfo.orderCapId}: ${error}`);
404
+ // Continue with next order without adding this one to the list
405
+ }
406
+ }));
407
+ }
408
+ return orderInfoList.sort((a, b) => a.createdAt > b.createdAt ? 1 : -1);
409
+ }
410
+ async hasReferral(referree) {
411
+ const raw = await this.getReferralData(referree);
412
+ return !raw.error;
413
+ }
414
+ async getReferralData(referree) {
415
+ const raw = await this.provider.getDynamicFieldObject({
416
+ parentId: this.consts.zoCore.referralsParent,
417
+ name: {
418
+ type: 'address',
419
+ value: referree,
420
+ },
421
+ });
422
+ return raw;
423
+ }
424
+ /**
425
+ * Gets rebase fee model for ZBTCVC
426
+ */
427
+ async getRebaseFeeModel() {
428
+ this.validateCache();
429
+ if (this.rebaseFeeModelCache) {
430
+ return this.rebaseFeeModelCache;
431
+ }
432
+ const rawData = await this.provider.getObject({
433
+ id: this.consts.zoCore.rebaseFeeModel,
434
+ options: {
435
+ showContent: true,
436
+ },
437
+ });
438
+ return ZBTCVCDataAPI.parseRebaseFeeModel(rawData);
439
+ }
440
+ async fundingFeeRate(indexToken, long) {
441
+ const symbol = await this.getSymbolInfo(indexToken, long);
442
+ if (symbol.lastUpdate <= 0) {
443
+ return 0;
444
+ }
445
+ const price = (await this.getOraclePrice(indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked();
446
+ const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals;
447
+ const model = symbol.fundingFeeModel;
448
+ const elapsed = consts_1.SECONDS_PER_EIGHT_HOUR;
449
+ const deltaSize = ZBTCVCDataAPI.calcDeltaSize(symbol, price);
450
+ const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
451
+ return ZBTCVCDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed);
452
+ }
453
+ async rebaseFeeRate(collateralToken, increase, amount) {
454
+ let vaultValue = 0;
455
+ if (!increase && amount > 0) {
456
+ amount = -amount;
457
+ }
458
+ const value = amount * (await this.getOraclePrice(collateralToken)).getPriceUnchecked().getPriceAsNumberUnchecked() / (10 ** this.consts.coins[collateralToken].decimals);
459
+ const vaultPromises = Object.keys(this.consts.zoCore.vaults).map(async (vault) => {
460
+ const vaultInfo = await this.getVaultInfo(vault);
461
+ const reservingFeeDelta = ZBTCVCDataAPI.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
462
+ const res = (reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount) * (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked() / (10 ** this.consts.coins[vault].decimals);
463
+ if (collateralToken === vault) {
464
+ vaultValue = res;
465
+ }
466
+ return res;
467
+ });
468
+ const vaultValues = await Promise.all(vaultPromises);
469
+ const totalVaultValue = vaultValues.reduce((acc, curr) => acc + curr, 0);
470
+ const targetRatio = Number.parseInt(this.consts.zoCore.vaults[collateralToken].weight, 10) / Object.values(this.consts.zoCore.vaults)
471
+ .map(e => Number.parseInt(e.weight, 10))
472
+ .reduce((acc, curr) => acc + curr, 0);
473
+ return ZBTCVCDataAPI.calcRebaseFeeRate(await this.getRebaseFeeModel(), increase, (vaultValue + value) / (totalVaultValue + value), targetRatio);
474
+ }
475
+ async reservingFeeRate(collateralToken, amount = 0) {
476
+ const vaultInfo = await this.getVaultInfo(collateralToken);
477
+ const vaultSupply = vaultInfo.liquidity + vaultInfo.reservedAmount + vaultInfo.unrealisedReservingFeeAmount + amount;
478
+ const utilization = vaultSupply ? ((vaultInfo.reservedAmount + amount) / vaultSupply) : 0;
479
+ return ZBTCVCDataAPI.calcReservingFeeRate(vaultInfo.reservingFeeModel, utilization, consts_1.SECONDS_PER_EIGHT_HOUR);
480
+ }
481
+ async getHistory(trader, page, limit, orderType, symbol) {
482
+ const params = new URLSearchParams({
483
+ trader,
484
+ page: page.toString(),
485
+ limit: limit.toString(),
486
+ });
487
+ // Add filter parameters if provided
488
+ if (orderType && orderType !== 'all') {
489
+ params.append('orderType', orderType);
490
+ }
491
+ if (symbol && symbol !== 'all') {
492
+ params.append('symbol', symbol);
493
+ }
494
+ params.append('lpType', 'ZBTCVC');
495
+ const url = `${this.apiEndpoint}/traderEvents?${params}`;
496
+ const res = await fetch(url, {
497
+ method: 'GET',
498
+ headers: {
499
+ 'Content-Type': 'application/json',
500
+ },
501
+ });
502
+ const response = await res.json();
503
+ return {
504
+ histories: response.data?.histories || [],
505
+ pagination: response.data?.pagination || {
506
+ total: 0,
507
+ page: 1,
508
+ limit: 20,
509
+ pages: 0,
510
+ },
511
+ };
512
+ }
513
+ // Private helper methods
514
+ static calcFundingFeeRate(model, pnlPerRate, elapsed) {
515
+ const dailyRate = Math.min(model.multiplier * Math.abs(pnlPerRate), model.max);
516
+ const secondsRate = dailyRate * elapsed / consts_1.SECONDS_PER_EIGHT_HOUR;
517
+ return pnlPerRate >= 0 ? -secondsRate : secondsRate;
518
+ }
519
+ static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp) {
520
+ if (symbol.lastUpdate > 0) {
521
+ const elapsed = timestamp - symbol.lastUpdate;
522
+ if (elapsed > 0) {
523
+ const deltaSize = ZBTCVCDataAPI.calcDeltaSize(symbol, price);
524
+ const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
525
+ return symbol.accFundingRate + ZBTCVCDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed);
526
+ }
527
+ }
528
+ return symbol.accFundingRate;
529
+ }
530
+ static calculateSymbolFundingFee(symbol, model, price, lpSupplyAmount, timestamp) {
531
+ const accFundingRate = ZBTCVCDataAPI.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp);
532
+ return symbol.unrealisedFundingFeeValue + (accFundingRate - symbol.accFundingRate) * symbol.openingSize;
533
+ }
534
+ static calculatePositionReserveFee(position, vault, model, timestamp) {
535
+ const accReservingRate = ZBTCVCDataAPI.calcAccReservingFeeRate(vault, model, timestamp);
536
+ return position.reservingFeeAmount + (accReservingRate - vault.accReservingRate) * position.collateralAmount;
537
+ }
538
+ static calcAccReservingFeeRate(vault, model, timestamp) {
539
+ if (vault.lastUpdate > 0) {
540
+ const elapsed = timestamp - vault.lastUpdate;
541
+ if (elapsed > 0) {
542
+ const utilization = ZBTCVCDataAPI.vaultUtilization(vault);
543
+ return vault.accReservingRate + ZBTCVCDataAPI.calcReservingFeeRate(model, utilization, elapsed);
544
+ }
545
+ }
546
+ return vault.accReservingRate;
547
+ }
548
+ static calcRebaseFeeRate(model, increase, ratio, targetRatio) {
549
+ if ((increase && ratio <= targetRatio) || (!increase && ratio >= targetRatio)) {
550
+ return model.base;
551
+ }
552
+ return model.base + model.multiplier * Math.abs(ratio - targetRatio);
553
+ }
554
+ static vaultUtilization(vault) {
555
+ const supplyAmount = vault.liquidity + vault.reservedAmount + vault.unrealisedReservingFeeAmount;
556
+ if (supplyAmount === 0) {
557
+ return 0;
558
+ }
559
+ return vault.reservedAmount / supplyAmount;
560
+ }
561
+ static calcReservingFeeRate(model, utilization, elapsed) {
562
+ return model.multiplier * utilization * elapsed / consts_1.SECONDS_PER_EIGHT_HOUR;
563
+ }
564
+ static calcDeltaSize(symbol, price) {
565
+ const latestSize = symbol.openingAmount / symbol.priceConfig.precision * price;
566
+ return symbol.long ? symbol.openingSize - latestSize : latestSize - symbol.openingSize;
567
+ }
568
+ static parseMarketInfo(raw) {
569
+ const content = raw.data.content.fields;
570
+ return {
571
+ lpSupply: content.lp_supply.fields.value,
572
+ positionId: content.positions.fields.id.id,
573
+ vaultId: content.vaults.fields.id.id,
574
+ symbolId: content.symbols.fields.id.id,
575
+ referralId: content.referrals.fields.id.id,
576
+ orderId: content.orders.fields.id.id,
577
+ rebaseFeeModel: content.rebase_fee_model,
578
+ lpSupplyWithDecimals: content.lp_supply.fields.value / (10 ** consts_1.ZBTCVC_TOKEN_DECIMALS),
579
+ };
580
+ }
581
+ async parseVaultInfo(raw) {
582
+ const vaultFields = raw.data.content.fields.value.fields;
583
+ const reservingFeeModelAddr = vaultFields.reserving_fee_model;
584
+ const reservingFeeModelRaw = await this.provider.getObject({
585
+ id: reservingFeeModelAddr,
586
+ options: {
587
+ showContent: true,
588
+ },
589
+ });
590
+ const reservingFeeModel = ZBTCVCDataAPI.parseReservingFeeModel(reservingFeeModelRaw);
591
+ return {
592
+ liquidity: (0, utils_2.parseValue)(vaultFields.liquidity),
593
+ reservedAmount: (0, utils_2.parseValue)(vaultFields.reserved_amount),
594
+ unrealisedReservingFeeAmount: (0, utils_2.parseValue)(vaultFields.unrealised_reserving_fee_amount),
595
+ accReservingRate: (0, utils_2.parseValue)(vaultFields.acc_reserving_rate),
596
+ enabled: vaultFields.enabled,
597
+ weight: (0, utils_2.parseValue)(vaultFields.weight),
598
+ lastUpdate: (0, utils_2.parseValue)(vaultFields.last_update),
599
+ reservingFeeModel,
600
+ priceConfig: {
601
+ maxInterval: (0, utils_2.parseValue)(vaultFields.price_config.fields.max_interval),
602
+ maxConfidence: (0, utils_2.parseValue)(vaultFields.price_config.fields.max_confidence),
603
+ precision: (0, utils_2.parseValue)(vaultFields.price_config.fields.precision),
604
+ feeder: vaultFields.price_config.fields.feeder,
605
+ },
606
+ };
607
+ }
608
+ async parseSymbolInfo(raw, long) {
609
+ const { objectId } = raw.data;
610
+ const { fields } = raw.data.content.fields.value;
611
+ const fundingFeeModelAddr = fields.funding_fee_model;
612
+ const fundingFeeModelRaw = await this.provider.getObject({
613
+ id: fundingFeeModelAddr,
614
+ options: {
615
+ showContent: true,
616
+ },
617
+ });
618
+ const fundingFeeModel = ZBTCVCDataAPI.parseFundingFeeModel(fundingFeeModelRaw);
619
+ return {
620
+ objectId,
621
+ openingSize: (0, utils_2.parseValue)(fields.opening_size),
622
+ openingAmount: (0, utils_2.parseValue)(fields.opening_amount),
623
+ accFundingRate: (0, utils_2.parseValue)(fields.acc_funding_rate),
624
+ realisedPnl: (0, utils_2.parseValue)(fields.realised_pnl),
625
+ unrealisedFundingFeeValue: (0, utils_2.parseValue)(fields.unrealised_funding_fee_value),
626
+ openEnabled: fields.open_enabled,
627
+ liquidateEnabled: fields.liquidate_enabled,
628
+ decreaseEnabled: fields.decrease_enabled,
629
+ lastUpdate: (0, utils_2.parseValue)(fields.last_update),
630
+ fundingFeeModel,
631
+ long,
632
+ priceConfig: {
633
+ maxInterval: (0, utils_2.parseValue)(fields.price_config.fields.max_interval),
634
+ maxConfidence: (0, utils_2.parseValue)(fields.price_config.fields.max_confidence),
635
+ precision: (0, utils_2.parseValue)(fields.price_config.fields.precision),
636
+ feeder: fields.price_config.fields.feeder,
637
+ },
638
+ };
639
+ }
640
+ static parsePositionConfig(raw) {
641
+ const positionConfigFields = raw.data.content.fields.inner.fields;
642
+ return {
643
+ decreaseFeeBps: (0, utils_2.parseValue)(positionConfigFields.decrease_fee_bps),
644
+ liquidationBonus: (0, utils_2.parseValue)(positionConfigFields.liquidation_bonus),
645
+ liquidationThreshold: (0, utils_2.parseValue)(positionConfigFields.liquidation_threshold),
646
+ maxLeverage: (0, utils_2.parseValue)(positionConfigFields.max_leverage),
647
+ minHoldingDuration: (0, utils_2.parseValue)(positionConfigFields.min_holding_duration),
648
+ openFeeBps: (0, utils_2.parseValue)(positionConfigFields.open_fee_bps),
649
+ maxReservedMultiplier: (0, utils_2.parseValue)(positionConfigFields.max_reserved_multiplier),
650
+ minCollateralValue: (0, utils_2.parseValue)(positionConfigFields.min_collateral_value),
651
+ };
652
+ }
653
+ static parseSymbolConfig(raw) {
654
+ const { fields } = raw.data.content;
655
+ return {
656
+ id: fields.id.id,
657
+ max_opening_size: (0, utils_2.parseValue)(fields.max_opening_size),
658
+ max_opening_size_enabled: fields.max_opening_size_enabled,
659
+ max_opening_size_per_position: (0, utils_2.parseValue)(fields.max_opening_size_per_position),
660
+ max_opening_size_per_position_enabled: fields.max_opening_size_per_position_enabled,
661
+ instant_exit_fee_config: {
662
+ instant_exit_tier_1_duration_threshold: (0, utils_2.parseValue)(fields.instant_exit_fee_config.fields.instant_exit_tier_1_duration_threshold),
663
+ instant_exit_tier_1_fee_bps: (0, utils_2.parseValue)(fields.instant_exit_fee_config.fields.instant_exit_tier_1_fee_bps.fields.value),
664
+ instant_exit_tier_1_fee_enabled: fields.instant_exit_fee_config.fields.instant_exit_tier_1_fee_enabled,
665
+ instant_exit_tier_2_duration_threshold: (0, utils_2.parseValue)(fields.instant_exit_fee_config.fields.instant_exit_tier_2_duration_threshold),
666
+ instant_exit_tier_2_fee_bps: (0, utils_2.parseValue)(fields.instant_exit_fee_config.fields.instant_exit_tier_2_fee_bps.fields.value),
667
+ instant_exit_tier_2_fee_enabled: fields.instant_exit_fee_config.fields.instant_exit_tier_2_fee_enabled,
668
+ instant_exit_tier_3_duration_threshold: (0, utils_2.parseValue)(fields.instant_exit_fee_config.fields.instant_exit_tier_3_duration_threshold),
669
+ instant_exit_tier_3_fee_bps: (0, utils_2.parseValue)(fields.instant_exit_fee_config.fields.instant_exit_tier_3_fee_bps.fields.value),
670
+ instant_exit_tier_3_fee_enabled: fields.instant_exit_fee_config.fields.instant_exit_tier_3_fee_enabled,
671
+ },
672
+ };
673
+ }
674
+ async parsePositionInfo(raw, id_) {
675
+ const { content } = raw.data;
676
+ const { fields } = content;
677
+ const positionFields = fields.value.fields;
678
+ const dataType = fields.name.type;
679
+ const positionInfo = {
680
+ id: id_,
681
+ long: dataType.includes('::market::LONG'),
682
+ owner: fields.name.fields.owner,
683
+ version: Number.parseInt(raw.data.version, 10),
684
+ collateralToken: (0, utils_2.suiSymbolToSymbol)(dataType.split('<')[1].split(',')[0].trim(), this.consts),
685
+ indexToken: (0, utils_2.suiSymbolToSymbol)(dataType.split(',')[1].trim(), this.consts),
686
+ collateralAmount: (0, utils_2.parseValue)(positionFields.collateral),
687
+ positionAmount: (0, utils_2.parseValue)(positionFields.position_amount),
688
+ reservedAmount: (0, utils_2.parseValue)(positionFields.reserved),
689
+ positionSize: (0, utils_2.parseValue)(positionFields.position_size),
690
+ lastFundingRate: (0, utils_2.parseValue)(positionFields.last_funding_rate),
691
+ lastReservingRate: (0, utils_2.parseValue)(positionFields.last_reserving_rate),
692
+ reservingFeeAmount: (0, utils_2.parseValue)(positionFields.reserving_fee_amount),
693
+ fundingFeeValue: (0, utils_2.parseValue)(positionFields.funding_fee_value),
694
+ closed: positionFields.closed,
695
+ openTimestamp: (0, utils_2.parseValue)(positionFields.open_timestamp),
696
+ };
697
+ positionInfo.reservingFeeAmount = ZBTCVCDataAPI.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000);
698
+ positionInfo.fundingFeeValue = ZBTCVCDataAPI.calculatePositionFundingFee(positionInfo, await this.getSymbolInfo(positionInfo.indexToken, positionInfo.long), (await this.getSymbolInfo(positionInfo.indexToken, positionInfo.long)).fundingFeeModel, (await this.getOraclePrice(positionInfo.indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked(), (await this.getMarketInfo()).lpSupplyWithDecimals, Date.now() / 1000);
699
+ return positionInfo;
700
+ }
701
+ static calculatePositionFundingFee(position, symbol, model, price, lpSupplyAmount, timestamp) {
702
+ const accFundingRate = ZBTCVCDataAPI.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp);
703
+ return position.fundingFeeValue + (accFundingRate - symbol.accFundingRate) * position.positionSize;
704
+ }
705
+ static parseRebaseFeeModel(raw) {
706
+ const { fields } = raw.data.content;
707
+ return {
708
+ base: (0, utils_2.parseValue)(fields.base),
709
+ multiplier: (0, utils_2.parseValue)(fields.multiplier),
710
+ };
711
+ }
712
+ static parseReservingFeeModel(raw) {
713
+ const content = raw.data.content.fields;
714
+ return {
715
+ multiplier: (0, utils_2.parseValue)(content.multiplier),
716
+ };
717
+ }
718
+ static parseFundingFeeModel(raw) {
719
+ const content = raw.data.content.fields;
720
+ return {
721
+ multiplier: (0, utils_2.parseValue)(content.multiplier),
722
+ max: (0, utils_2.parseValue)(content.max),
723
+ };
724
+ }
725
+ parseOrderInfo(raw, capId) {
726
+ const { content } = raw.data;
727
+ const { fields } = content.fields.value;
728
+ // Extract tokens from dataType
729
+ const dataType = content.type;
730
+ const orderType = content.fields.value.type.includes('OpenPositionOrder') ? 'OPEN_POSITION' : 'DECREASE_POSITION';
731
+ const ret = {
732
+ id: content.fields.id.id,
733
+ capId,
734
+ executed: fields.executed,
735
+ owner: content.fields.name.fields.owner,
736
+ collateralToken: (0, utils_2.suiSymbolToSymbol)(dataType.split('<')[2].split(',')[0].trim(), this.consts),
737
+ indexToken: (0, utils_2.suiSymbolToSymbol)(dataType.split(',')[1].trim(), this.consts),
738
+ feeToken: (0, utils_2.suiSymbolToSymbol)(dataType.split(',')[3].split('>')[0].trim(), this.consts),
739
+ indexPrice: (0, utils_2.parseValue)(fields.limited_index_price.fields.price || fields.limited_index_price),
740
+ collateralPriceThreshold: (0, utils_2.parseValue)(fields.collateral_price_threshold),
741
+ feeAmount: BigInt(fields.fee),
742
+ long: dataType.includes('::market::LONG'),
743
+ orderType,
744
+ createdAt: (0, utils_2.parseValue)(fields.created_at),
745
+ v11Order: !fields.limited_index_price.fields.price,
746
+ };
747
+ if (orderType === 'OPEN_POSITION') {
748
+ ret.openOrder = {
749
+ reserveAmount: BigInt(fields.reserve_amount),
750
+ collateralAmount: BigInt(fields.collateral),
751
+ openAmount: BigInt(fields.open_amount),
752
+ };
753
+ }
754
+ else {
755
+ ret.decreaseOrder = {
756
+ decreaseAmount: BigInt(fields.decrease_amount),
757
+ takeProfit: fields.take_profit,
758
+ };
759
+ }
760
+ return ret;
761
+ }
762
+ async getPastFee(days = 7) {
763
+ // TODO: Check with Sentio data
764
+ const url = `${this.apiEndpoint}/histories/proxy/fee?days=${days}`;
765
+ const res = await fetch(url, {
766
+ method: 'GET',
767
+ headers: {
768
+ 'Content-Type': 'application/json',
769
+ },
770
+ });
771
+ return Number.parseFloat(await res.text() || '0');
772
+ }
773
+ static calculateVaultReservingFee(vaultInfo, reservingFeeModel, currentTime) {
774
+ const timeDelta = currentTime - vaultInfo.lastUpdate;
775
+ const periods = Math.floor(timeDelta / consts_1.SECONDS_PER_EIGHT_HOUR);
776
+ return vaultInfo.unrealisedReservingFeeAmount
777
+ + (vaultInfo.reservedAmount * reservingFeeModel.multiplier * periods) / 1e18;
778
+ }
779
+ static parseCredential(raw, pool) {
780
+ const stakedAmount = BigInt(raw.data.content.fields.stake);
781
+ const accRewardPerShare = BigInt(raw.data.content.fields.acc_reward_per_share);
782
+ return {
783
+ id: raw.data.objectId,
784
+ lockUntil: (0, utils_2.parseValue)(raw.data.content.fields.lock_until),
785
+ amount: stakedAmount,
786
+ accRewardPerShare,
787
+ claimable: ((pool.accRewardPerShare - accRewardPerShare) * stakedAmount)
788
+ / BigInt(1e18),
789
+ };
790
+ }
791
+ static parseStakePool(raw) {
792
+ const content = raw.data.content.fields;
793
+ const pool = {
794
+ id: content.id.id,
795
+ enabled: content.enabled,
796
+ lastUpdatedTime: (0, utils_2.parseValue)(content.last_updated_time),
797
+ stakedAmount: BigInt(content.staked_amount),
798
+ reward: BigInt(content.reward_vault),
799
+ startTime: (0, utils_2.parseValue)(content.start_time),
800
+ endTime: (0, utils_2.parseValue)(content.end_time),
801
+ rewardRate: BigInt(content.reward_rate),
802
+ accRewardPerShare: BigInt(content.acc_reward_per_share),
803
+ lockDuration: (0, utils_2.parseValue)(content.lock_duration),
804
+ };
805
+ ZBTCVCDataAPI.refreshPool(pool, Math.floor(Date.now() / 1000));
806
+ return pool;
807
+ }
808
+ static refreshPool(pool, timestamp) {
809
+ if (timestamp <= pool.lastUpdatedTime || timestamp < pool.startTime) {
810
+ return;
811
+ }
812
+ const applicableEndTime = Math.max(pool.endTime, pool.lastUpdatedTime);
813
+ const calculationEndTime = Math.min(timestamp, applicableEndTime);
814
+ if (calculationEndTime > pool.lastUpdatedTime && pool.stakedAmount > BigInt(0) && pool.rewardRate > BigInt(0)) {
815
+ const timeDiff = BigInt(calculationEndTime - pool.lastUpdatedTime);
816
+ const rewardAmount = timeDiff * pool.rewardRate;
817
+ const rewardPerShare = (rewardAmount * BigInt(1e18)) / pool.stakedAmount;
818
+ pool.accRewardPerShare += rewardPerShare;
819
+ }
820
+ pool.lastUpdatedTime = calculationEndTime;
821
+ }
822
+ }
823
+ exports.ZBTCVCDataAPI = ZBTCVCDataAPI;
824
+ //# sourceMappingURL=ZBTCVCDataAPI.cjs.map