@scallop-io/sui-scallop-sdk 1.4.1 → 1.4.2-rc.1

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 (80) hide show
  1. package/dist/constants/common.d.ts +1 -1
  2. package/dist/constants/poolAddress.d.ts +16 -4
  3. package/dist/constants/queryKeys.d.ts +2 -2
  4. package/dist/constants/tokenBucket.d.ts +2 -2
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +1270 -588
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +1225 -544
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/models/scallopBuilder.d.ts +2 -1
  11. package/dist/models/scallopCache.d.ts +2 -0
  12. package/dist/models/scallopQuery.d.ts +38 -20
  13. package/dist/models/scallopUtils.d.ts +4 -2
  14. package/dist/queries/borrowIncentiveQuery.d.ts +12 -0
  15. package/dist/queries/coreQuery.d.ts +18 -19
  16. package/dist/queries/index.d.ts +2 -0
  17. package/dist/queries/isolatedAssetQuery.d.ts +2 -2
  18. package/dist/queries/objectsQuery.d.ts +3 -0
  19. package/dist/queries/poolAddressesQuery.d.ts +18 -0
  20. package/dist/queries/spoolQuery.d.ts +6 -2
  21. package/dist/test.d.ts +1 -0
  22. package/dist/types/builder/borrowIncentive.d.ts +5 -5
  23. package/dist/types/builder/core.d.ts +20 -16
  24. package/dist/types/builder/loyaltyProgram.d.ts +1 -1
  25. package/dist/types/builder/referral.d.ts +4 -4
  26. package/dist/types/builder/sCoin.d.ts +2 -2
  27. package/dist/types/builder/spool.d.ts +4 -4
  28. package/dist/types/builder/vesca.d.ts +6 -6
  29. package/dist/types/query/core.d.ts +22 -5
  30. package/dist/types/query/spool.d.ts +20 -0
  31. package/dist/types/utils.d.ts +7 -2
  32. package/dist/utils/core.d.ts +2 -0
  33. package/dist/utils/index.d.ts +2 -0
  34. package/dist/utils/query.d.ts +1 -1
  35. package/dist/utils/util.d.ts +1 -0
  36. package/package.json +7 -7
  37. package/src/builders/borrowIncentiveBuilder.ts +28 -15
  38. package/src/builders/coreBuilder.ts +76 -49
  39. package/src/builders/loyaltyProgramBuilder.ts +4 -3
  40. package/src/builders/referralBuilder.ts +23 -10
  41. package/src/builders/sCoinBuilder.ts +8 -6
  42. package/src/builders/spoolBuilder.ts +21 -14
  43. package/src/builders/vescaBuilder.ts +23 -13
  44. package/src/constants/common.ts +1 -12
  45. package/src/constants/poolAddress.ts +336 -10
  46. package/src/constants/queryKeys.ts +9 -5
  47. package/src/constants/testAddress.ts +42 -0
  48. package/src/constants/tokenBucket.ts +2 -2
  49. package/src/index.ts +1 -0
  50. package/src/models/scallopBuilder.ts +59 -2
  51. package/src/models/scallopCache.ts +171 -19
  52. package/src/models/scallopClient.ts +16 -10
  53. package/src/models/scallopQuery.ts +36 -28
  54. package/src/models/scallopUtils.ts +11 -4
  55. package/src/queries/borrowIncentiveQuery.ts +6 -8
  56. package/src/queries/borrowLimitQuery.ts +1 -0
  57. package/src/queries/coreQuery.ts +408 -258
  58. package/src/queries/index.ts +2 -0
  59. package/src/queries/isolatedAssetQuery.ts +37 -31
  60. package/src/queries/objectsQuery.ts +20 -0
  61. package/src/queries/poolAddressesQuery.ts +146 -0
  62. package/src/queries/portfolioQuery.ts +31 -13
  63. package/src/queries/priceQuery.ts +3 -1
  64. package/src/queries/spoolQuery.ts +189 -122
  65. package/src/test.ts +17 -0
  66. package/src/types/builder/borrowIncentive.ts +8 -5
  67. package/src/types/builder/core.ts +23 -17
  68. package/src/types/builder/loyaltyProgram.ts +1 -1
  69. package/src/types/builder/referral.ts +6 -4
  70. package/src/types/builder/sCoin.ts +2 -2
  71. package/src/types/builder/spool.ts +4 -4
  72. package/src/types/builder/vesca.ts +9 -6
  73. package/src/types/query/core.ts +21 -5
  74. package/src/types/query/spool.ts +21 -0
  75. package/src/types/utils.ts +8 -3
  76. package/src/utils/core.ts +18 -0
  77. package/src/utils/index.ts +2 -0
  78. package/src/utils/query.ts +21 -5
  79. package/src/utils/tokenBucket.ts +9 -29
  80. package/src/utils/util.ts +8 -0
@@ -28,7 +28,7 @@ export type BalanceSheet = {
28
28
  revenue: string;
29
29
  };
30
30
 
31
- export type BorrowIndex = {
31
+ export type BorrowDynamic = {
32
32
  borrow_index: string;
33
33
  interest_rate: {
34
34
  fields: {
@@ -39,6 +39,8 @@ export type BorrowIndex = {
39
39
  last_updated: string;
40
40
  };
41
41
 
42
+ export type BorrowFee = { value: string };
43
+
42
44
  export type InterestModel = {
43
45
  base_borrow_rate_per_sec: {
44
46
  fields: {
@@ -161,7 +163,7 @@ export type MarketCollateral = {
161
163
  | 'collateralFactor'
162
164
  | 'liquidationFactor'
163
165
  | 'liquidationDiscount'
164
- | 'liquidationPanelty'
166
+ | 'liquidationPenalty'
165
167
  | 'liquidationReserveFactor'
166
168
  >
167
169
  > &
@@ -187,6 +189,9 @@ export type OriginMarketPoolData = {
187
189
  highKink: { value: string };
188
190
  midKink: { value: string };
189
191
  minBorrowAmount: string;
192
+ isIsolated: boolean;
193
+ supplyLimit: string;
194
+ borrowLimit: string;
190
195
  };
191
196
 
192
197
  export type ParsedMarketPoolData = {
@@ -209,6 +214,9 @@ export type ParsedMarketPoolData = {
209
214
  highKink: number;
210
215
  midKink: number;
211
216
  minBorrowAmount: number;
217
+ isIsolated: boolean;
218
+ supplyLimit: number;
219
+ borrowLimit: number;
212
220
  };
213
221
 
214
222
  export type CalculatedMarketPoolData = {
@@ -218,6 +226,8 @@ export type CalculatedMarketPoolData = {
218
226
  borrowApyOnHighKink: number;
219
227
  borrowAprOnMidKink: number;
220
228
  borrowApyOnMidKink: number;
229
+ coinDecimal: number;
230
+ conversionRate: number;
221
231
  maxBorrowApr: number;
222
232
  maxBorrowApy: number;
223
233
  borrowApr: number;
@@ -233,15 +243,18 @@ export type CalculatedMarketPoolData = {
233
243
  utilizationRate: number;
234
244
  supplyApr: number;
235
245
  supplyApy: number;
236
- conversionRate: number;
246
+ isIsolated: boolean;
247
+ maxSupplyCoin: number;
248
+ maxBorrowCoin: number;
237
249
  };
238
250
 
239
251
  export type OriginMarketCollateralData = {
240
252
  type: { name: string };
253
+ isIsolated: boolean;
241
254
  collateralFactor: { value: string };
242
255
  liquidationFactor: { value: string };
243
256
  liquidationDiscount: { value: string };
244
- liquidationPanelty: { value: string };
257
+ liquidationPenalty: { value: string };
245
258
  liquidationReserveFactor: { value: string };
246
259
  maxCollateralAmount: string;
247
260
  totalCollateralAmount: string;
@@ -252,13 +265,16 @@ export type ParsedMarketCollateralData = {
252
265
  collateralFactor: number;
253
266
  liquidationFactor: number;
254
267
  liquidationDiscount: number;
255
- liquidationPanelty: number;
268
+ liquidationPenalty: number;
256
269
  liquidationReserveFactor: number;
257
270
  maxCollateralAmount: number;
258
271
  totalCollateralAmount: number;
272
+ isIsolated: boolean;
259
273
  };
260
274
 
261
275
  export type CalculatedMarketCollateralData = {
276
+ coinDecimal: number;
277
+ isIsolated: boolean;
262
278
  maxDepositAmount: number;
263
279
  maxDepositCoin: number;
264
280
  depositAmount: number;
@@ -37,6 +37,27 @@ export type OriginSpoolData = {
37
37
  lastUpdate: string;
38
38
  };
39
39
 
40
+ export type SpoolData = {
41
+ created_at: string;
42
+ distributed_point: string;
43
+ distributed_point_per_period: string;
44
+ id: {
45
+ id: string;
46
+ };
47
+ index: string;
48
+ last_update: string;
49
+ max_distributed_point: string;
50
+ max_stakes: string;
51
+ point_distribution_time: string;
52
+ stake_type: {
53
+ type: string;
54
+ fields: {
55
+ name: string;
56
+ };
57
+ };
58
+ stakes: string;
59
+ };
60
+
40
61
  export type ParsedSpoolData = {
41
62
  stakeType: string;
42
63
  maxPoint: number;
@@ -11,10 +11,15 @@ export type PoolAddressInfo = {
11
11
  coingeckoId: string;
12
12
  decimal: number;
13
13
  pythFeedId: string;
14
- lendingPoolAddress: string;
15
- collateralPoolAddress?: string;
14
+ lendingPoolAddress?: string;
15
+ collateralPoolAddress?: string; // not all pool has collateral
16
+ borrowDynamic?: string;
17
+ interestModelId?: string;
18
+ borrowFeeKey?: string;
19
+ supplyLimitKey?: string;
20
+ borrowLimitKey?: string;
21
+ isolatedAssetKey?: string;
16
22
  sCoinAddress: string | undefined;
17
23
  marketCoinAddress: string;
18
- coinAddress: string;
19
24
  sCoinName: string | undefined;
20
25
  };
@@ -0,0 +1,18 @@
1
+ import { SuiObjectData } from '@mysten/sui/client';
2
+
3
+ export const parseObjectAs = <T>(object: SuiObjectData): T => {
4
+ if (!(object && object.content && 'fields' in object.content))
5
+ throw new Error(`Failed to parse object`);
6
+
7
+ const fields = object.content.fields as any;
8
+
9
+ if (typeof fields === 'object' && 'value' in fields) {
10
+ const value = fields.value;
11
+ if (typeof value === 'object' && 'fields' in value)
12
+ return value.fields as T;
13
+ return value as T;
14
+ } else if (typeof fields === 'object') {
15
+ return fields as T;
16
+ }
17
+ return fields as T;
18
+ };
@@ -3,3 +3,5 @@ export * from './query';
3
3
  export * from './util';
4
4
  export * from './tokenBucket';
5
5
  export * from './indexer';
6
+ export * from './core';
7
+ export * from './tokenBucket';
@@ -62,6 +62,9 @@ export const parseOriginMarketPoolData = (
62
62
  highKink: Number(originMarketPoolData.highKink.value) / 2 ** 32,
63
63
  midKink: Number(originMarketPoolData.midKink.value) / 2 ** 32,
64
64
  minBorrowAmount: Number(originMarketPoolData.minBorrowAmount),
65
+ isIsolated: originMarketPoolData.isIsolated,
66
+ supplyLimit: Number(originMarketPoolData.supplyLimit),
67
+ borrowLimit: Number(originMarketPoolData.borrowLimit),
65
68
  };
66
69
  };
67
70
 
@@ -142,6 +145,7 @@ export const calculateMarketPoolData = (
142
145
  borrowApyOnHighKink: utils.parseAprToApy(borrowAprOnHighKink),
143
146
  borrowAprOnMidKink,
144
147
  borrowApyOnMidKink: utils.parseAprToApy(borrowAprOnMidKink),
148
+ coinDecimal,
145
149
  maxBorrowApr,
146
150
  maxBorrowApy: utils.parseAprToApy(maxBorrowApr),
147
151
  borrowApr: Math.min(borrowApr, maxBorrowApr),
@@ -161,6 +165,13 @@ export const calculateMarketPoolData = (
161
165
  supplyApr: supplyApr.toNumber(),
162
166
  supplyApy: utils.parseAprToApy(supplyApr.toNumber()),
163
167
  conversionRate: conversionRate.toNumber(),
168
+ isIsolated: parsedMarketPoolData.isIsolated,
169
+ maxSupplyCoin: BigNumber(parsedMarketPoolData.supplyLimit)
170
+ .shiftedBy(coinDecimal)
171
+ .toNumber(),
172
+ maxBorrowCoin: BigNumber(parsedMarketPoolData.borrowLimit)
173
+ .shiftedBy(coinDecimal)
174
+ .toNumber(),
164
175
  };
165
176
  };
166
177
 
@@ -176,14 +187,15 @@ export const parseOriginMarketCollateralData = (
176
187
  const divisor = 2 ** 32;
177
188
  return {
178
189
  coinType: normalizeStructTag(originMarketCollateralData.type.name),
190
+ isIsolated: originMarketCollateralData.isIsolated,
179
191
  collateralFactor:
180
192
  Number(originMarketCollateralData.collateralFactor.value) / divisor,
181
193
  liquidationFactor:
182
194
  Number(originMarketCollateralData.liquidationFactor.value) / divisor,
183
195
  liquidationDiscount:
184
196
  Number(originMarketCollateralData.liquidationDiscount.value) / divisor,
185
- liquidationPanelty:
186
- Number(originMarketCollateralData.liquidationPanelty.value) / divisor,
197
+ liquidationPenalty:
198
+ Number(originMarketCollateralData.liquidationPenalty.value) / divisor,
187
199
  liquidationReserveFactor:
188
200
  Number(originMarketCollateralData.liquidationReserveFactor.value) /
189
201
  divisor,
@@ -212,6 +224,8 @@ export const calculateMarketCollateralData = (
212
224
  ).shiftedBy(-1 * coinDecimal);
213
225
 
214
226
  return {
227
+ coinDecimal,
228
+ isIsolated: parsedMarketCollateralData.isIsolated,
215
229
  maxDepositAmount: parsedMarketCollateralData.maxCollateralAmount,
216
230
  maxDepositCoin: maxCollateralCoin.toNumber(),
217
231
  depositAmount: parsedMarketCollateralData.totalCollateralAmount,
@@ -423,6 +437,7 @@ export const parseOriginBorrowIncentivesPoolPointData = (
423
437
  * @return Parsed borrow incentive pool data
424
438
  */
425
439
  export const parseOriginBorrowIncentivePoolData = (
440
+ utils: ScallopUtils,
426
441
  originBorrowIncentivePoolData: OriginBorrowIncentivePoolData
427
442
  ): ParsedBorrowIncentivePoolData => {
428
443
  return {
@@ -433,9 +448,10 @@ export const parseOriginBorrowIncentivePoolData = (
433
448
  poolPoints: originBorrowIncentivePoolData.points.reduce(
434
449
  (acc, point) => {
435
450
  const parsed = parseOriginBorrowIncentivesPoolPointData(point);
436
- const name = parseStructTag(
437
- parsed.pointType
438
- ).name.toLowerCase() as SupportBorrowIncentiveRewardCoins;
451
+ const name = utils.parseSCoinTypeNameToMarketCoinName(
452
+ parseStructTag(parsed.pointType).name.toLowerCase()
453
+ ) as SupportBorrowIncentiveRewardCoins;
454
+
439
455
  acc[name] = parsed;
440
456
  return acc;
441
457
  },
@@ -16,11 +16,14 @@ class TokenBucket {
16
16
  refill() {
17
17
  const now = Date.now();
18
18
  const elapsed = now - this.lastRefill;
19
- if (elapsed > this.interval) {
19
+
20
+ if (elapsed >= this.interval) {
20
21
  const tokensToAdd =
21
22
  Math.floor(elapsed / this.interval) * this.tokensPerInterval;
22
23
  this.tokens = Math.min(this.tokens + tokensToAdd, this.tokensPerInterval);
23
- this.lastRefill = now;
24
+
25
+ // Update lastRefill to reflect the exact time of the last "refill"
26
+ this.lastRefill += Math.floor(elapsed / this.interval) * this.interval;
24
27
  }
25
28
  }
26
29
 
@@ -39,41 +42,18 @@ const callWithRateLimit = async <T>(
39
42
  fn: () => Promise<T>,
40
43
  retryDelayInMs = DEFAULT_INTERVAL_IN_MS,
41
44
  maxRetries = 15,
42
- backoffFactor = 2 // The factor by which to increase the delay
45
+ backoffFactor = 1.25 // The factor by which to increase the delay
43
46
  ): Promise<T | null> => {
44
47
  let retries = 0;
45
48
 
46
49
  const tryRequest = async (): Promise<T | null> => {
47
50
  if (tokenBucket.removeTokens(1)) {
48
- try {
49
- const result = await fn();
50
-
51
- // Check if the result is an object with status code (assuming the response has a status property)
52
- if (result && (result as any).status === 429) {
53
- throw new Error('Unexpected status code: 429');
54
- }
55
-
56
- return result;
57
- } catch (error: any) {
58
- if (
59
- error.message === 'Unexpected status code: 429' &&
60
- retries < maxRetries
61
- ) {
62
- retries++;
63
- const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
64
- // console.warn(`429 encountered, retrying in ${delay} ms`);
65
- await new Promise((resolve) => setTimeout(resolve, delay));
66
- return tryRequest();
67
- } else {
68
- // console.error(error);
69
- console.error('An error occurred:', error.message);
70
- return null;
71
- }
72
- }
51
+ const result = await fn();
52
+ return result;
73
53
  } else if (retries < maxRetries) {
74
54
  retries++;
75
55
  const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
76
- // console.warn(`Rate limit exceeded, retrying in ${delay} ms`);
56
+ // console.error(`Rate limit exceeded, retrying in ${delay} ms`);
77
57
  await new Promise((resolve) => setTimeout(resolve, delay));
78
58
  return tryRequest();
79
59
  } else {
package/src/utils/util.ts CHANGED
@@ -127,3 +127,11 @@ export const findClosestUnlockRound = (unlockAtInSecondTimestamp: number) => {
127
127
  }
128
128
  return Math.floor(closestTwelveAM.getTime() / 1000);
129
129
  };
130
+
131
+ export const partitionArray = <T>(array: T[], chunkSize: number) => {
132
+ const result: T[][] = [];
133
+ for (let i = 0; i < array.length; i += chunkSize) {
134
+ result.push(array.slice(i, i + chunkSize));
135
+ }
136
+ return result;
137
+ };