@scallop-io/sui-scallop-sdk 0.46.54 → 0.46.56

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 (54) hide show
  1. package/dist/constants/common.d.ts +1 -1
  2. package/dist/constants/pyth.d.ts +1 -1
  3. package/dist/index.js +1752 -1605
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1711 -1564
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/models/scallop.d.ts +1 -1
  8. package/dist/models/scallopAddress.d.ts +4 -4
  9. package/dist/models/scallopBuilder.d.ts +2 -2
  10. package/dist/models/scallopCache.d.ts +2 -2
  11. package/dist/models/scallopClient.d.ts +7 -2
  12. package/dist/models/scallopIndexer.d.ts +3 -3
  13. package/dist/models/scallopPrice.d.ts +0 -0
  14. package/dist/models/scallopQuery.d.ts +10 -4
  15. package/dist/models/scallopUtils.d.ts +8 -7
  16. package/dist/queries/borrowIncentiveQuery.d.ts +10 -4
  17. package/dist/queries/coreQuery.d.ts +8 -4
  18. package/dist/queries/priceQuery.d.ts +7 -3
  19. package/dist/queries/referralQuery.d.ts +2 -2
  20. package/dist/queries/sCoinQuery.d.ts +18 -4
  21. package/dist/queries/spoolQuery.d.ts +10 -4
  22. package/dist/queries/vescaQuery.d.ts +7 -5
  23. package/dist/types/builder/vesca.d.ts +2 -1
  24. package/dist/types/model.d.ts +27 -12
  25. package/dist/types/query/core.d.ts +1 -0
  26. package/package.json +1 -1
  27. package/src/builders/borrowIncentiveBuilder.ts +19 -21
  28. package/src/builders/coreBuilder.ts +10 -8
  29. package/src/builders/loyaltyProgramBuilder.ts +2 -6
  30. package/src/builders/spoolBuilder.ts +2 -2
  31. package/src/builders/vescaBuilder.ts +12 -4
  32. package/src/constants/common.ts +2 -0
  33. package/src/constants/enum.ts +4 -0
  34. package/src/constants/pyth.ts +2 -2
  35. package/src/models/scallop.ts +14 -20
  36. package/src/models/scallopAddress.ts +15 -5
  37. package/src/models/scallopBuilder.ts +29 -25
  38. package/src/models/scallopCache.ts +2 -2
  39. package/src/models/scallopClient.ts +91 -32
  40. package/src/models/scallopIndexer.ts +15 -8
  41. package/src/models/scallopPrice.ts +0 -0
  42. package/src/models/scallopQuery.ts +47 -25
  43. package/src/models/scallopUtils.ts +75 -74
  44. package/src/queries/borrowIncentiveQuery.ts +40 -29
  45. package/src/queries/coreQuery.ts +38 -24
  46. package/src/queries/portfolioQuery.ts +1 -2
  47. package/src/queries/priceQuery.ts +20 -9
  48. package/src/queries/referralQuery.ts +4 -4
  49. package/src/queries/sCoinQuery.ts +95 -17
  50. package/src/queries/spoolQuery.ts +26 -14
  51. package/src/queries/vescaQuery.ts +32 -26
  52. package/src/types/builder/vesca.ts +8 -1
  53. package/src/types/model.ts +40 -11
  54. package/src/types/query/core.ts +1 -0
@@ -44,7 +44,7 @@ const requireObligationInfo = async (
44
44
  if (params.length === 4 && obligationId && obligationKey)
45
45
  return { obligationId, obligationKey };
46
46
  const sender = requireSender(txBlock);
47
- const obligations = await getObligations(builder.query, sender);
47
+ const obligations = await getObligations(builder, sender);
48
48
  if (obligations.length === 0) {
49
49
  throw new Error(`No obligation found for sender ${sender}`);
50
50
  }
@@ -391,10 +391,11 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
391
391
  obligationId,
392
392
  obligationKey
393
393
  );
394
- const obligationCoinNames = await builder.utils.getObligationCoinNames(
395
- obligationInfo.obligationId
396
- );
397
- const updateCoinNames = [...obligationCoinNames, poolCoinName];
394
+ const obligationCoinNames =
395
+ (await builder.utils.getObligationCoinNames(
396
+ obligationInfo.obligationId
397
+ )) ?? [];
398
+ const updateCoinNames = [...(obligationCoinNames ?? []), poolCoinName];
398
399
  await updateOracles(builder, txBlock, updateCoinNames);
399
400
  return txBlock.borrow(
400
401
  obligationInfo.obligationId,
@@ -416,9 +417,10 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
416
417
  obligationId,
417
418
  obligationKey
418
419
  );
419
- const obligationCoinNames = await builder.utils.getObligationCoinNames(
420
- obligationInfo.obligationId
421
- );
420
+ const obligationCoinNames =
421
+ (await builder.utils.getObligationCoinNames(
422
+ obligationInfo.obligationId
423
+ )) ?? [];
422
424
  const updateCoinNames = [...obligationCoinNames, poolCoinName];
423
425
  await updateOracles(builder, txBlock, updateCoinNames);
424
426
  return txBlock.borrowWithReferral(
@@ -1,5 +1,5 @@
1
1
  import { TransactionBlock } from '@mysten/sui.js/transactions';
2
- import { SuiObjectArg, SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
2
+ import { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
3
3
  import { coinIds } from 'src/constants';
4
4
  import { ScallopBuilder } from 'src/models';
5
5
  import {
@@ -43,7 +43,6 @@ const generateLoyaltyProgramQuickMethod: GenerateLoyaltyProgramQuickMethod = ({
43
43
  if (!veScaKey) throw new Error(`No veScaKey found for user ${sender}`);
44
44
 
45
45
  // claim the pending reward
46
- const toTransferObject: SuiObjectArg[] = [];
47
46
  const rewardCoin = txBlock.claimLoyaltyRevenue(veScaKey);
48
47
 
49
48
  // get existing sca coin to merge with
@@ -53,10 +52,7 @@ const generateLoyaltyProgramQuickMethod: GenerateLoyaltyProgramQuickMethod = ({
53
52
  coinIds.sca,
54
53
  requireSender(txBlock)
55
54
  );
56
-
57
- if (toTransferObject.length > 0) {
58
- txBlock.transferObjects(toTransferObject, sender);
59
- }
55
+ txBlock.transferObjects([rewardCoin], sender);
60
56
  },
61
57
  };
62
58
  };
@@ -42,7 +42,7 @@ const requireStakeAccountIds = async (
42
42
  const [builder, txBlock, stakeMarketCoinName, stakeAccountId] = params;
43
43
  if (params.length === 4 && stakeAccountId) return [stakeAccountId];
44
44
  const sender = requireSender(txBlock);
45
- const stakeAccounts = await getStakeAccounts(builder.query, sender);
45
+ const stakeAccounts = await getStakeAccounts(builder, sender);
46
46
  if (stakeAccounts[stakeMarketCoinName].length === 0) {
47
47
  throw new Error(`No stake account id found for sender ${sender}`);
48
48
  }
@@ -72,7 +72,7 @@ const requireStakeAccounts = async (
72
72
  ) => {
73
73
  const [builder, txBlock, stakeMarketCoinName, stakeAccountId] = params;
74
74
  const sender = requireSender(txBlock);
75
- const stakeAccounts = await getStakeAccounts(builder.query, sender);
75
+ const stakeAccounts = await getStakeAccounts(builder, sender);
76
76
  if (stakeAccounts[stakeMarketCoinName].length === 0) {
77
77
  throw new Error(`No stake account found for sender ${sender}`);
78
78
  }
@@ -22,6 +22,7 @@ import type {
22
22
  import type {
23
23
  GenerateVeScaNormalMethod,
24
24
  GenerateVeScaQuickMethod,
25
+ RedeemScaQuickReturnType,
25
26
  ScallopTxBlock,
26
27
  SuiTxBlockWithVeScaNormalMethods,
27
28
  VeScaTxBlock,
@@ -50,7 +51,7 @@ export const requireVeSca = async (
50
51
  ) => {
51
52
  const [builder, txBlock, veScaKey] = params;
52
53
  if (params.length === 3 && veScaKey && typeof veScaKey === 'string') {
53
- const veSca = await getVeSca(builder.query, veScaKey);
54
+ const veSca = await getVeSca(builder.utils, veScaKey);
54
55
 
55
56
  if (!veSca) {
56
57
  return undefined;
@@ -60,7 +61,7 @@ export const requireVeSca = async (
60
61
  }
61
62
 
62
63
  const sender = requireSender(txBlock);
63
- const veScas = await getVeScas(builder.query, sender);
64
+ const veScas = await getVeScas(builder, sender);
64
65
  if (veScas.length === 0) {
65
66
  return undefined;
66
67
  }
@@ -334,7 +335,10 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
334
335
  txBlock.transferObjects(transferObjects, sender);
335
336
  }
336
337
  },
337
- redeemScaQuick: async (veScaKey?: SuiObjectArg) => {
338
+ redeemScaQuick: async <S extends boolean>(
339
+ veScaKey?: SuiObjectArg,
340
+ transferSca: S = true as S
341
+ ) => {
338
342
  const sender = requireSender(txBlock);
339
343
  const veSca = await requireVeSca(builder, txBlock, veScaKey);
340
344
 
@@ -342,7 +346,11 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
342
346
 
343
347
  if (veSca) {
344
348
  const sca = txBlock.redeemSca(veSca.keyId);
345
- txBlock.transferObjects([sca], sender);
349
+ if (transferSca) {
350
+ txBlock.transferObjects([sca], sender);
351
+ return;
352
+ }
353
+ return sca as RedeemScaQuickReturnType<S>;
346
354
  }
347
355
  },
348
356
  };
@@ -83,6 +83,8 @@ export const SUPPORT_SCOIN = [
83
83
  'seth',
84
84
  'ssca',
85
85
  'scetus',
86
+ 'ssol',
87
+ 'sbtc',
86
88
  ] as const;
87
89
 
88
90
  export const SUPPORT_SPOOLS_REWARDS = ['sui'] as const;
@@ -68,6 +68,8 @@ export const sCoins: types.SCoins = {
68
68
  shasui: 'shasui',
69
69
  svsui: 'svsui',
70
70
  ssca: 'ssca',
71
+ ssol: 'ssol',
72
+ sbtc: 'sbtc',
71
73
  };
72
74
 
73
75
  export const stakeMarketCoins: types.StakeMarketCoins = {
@@ -150,6 +152,8 @@ export const sCoinIds: types.SCoinIds = {
150
152
  '0x9a2376943f7d22f88087c259c5889925f332ca4347e669dc37d54c2bf651af3c::scallop_ha_sui::SCALLOP_HA_SUI',
151
153
  svsui:
152
154
  '0xe1a1cc6bcf0001a015eab84bcc6713393ce20535f55b8b6f35c142e057a25fbe::scallop_v_sui::SCALLOP_V_SUI',
155
+ ssol: '0x1392650f2eca9e3f6ffae3ff89e42a3590d7102b80e2b430f674730bc30d3259::scallop_wormhole_sol::SCALLOP_WORMHOLE_SOL',
156
+ sbtc: '0x2cf76a9cf5d3337961d1154283234f94da2dcff18544dfe5cbdef65f319591b5::scallop_wormhole_btc::SCALLOP_WORMHOLE_BTC',
153
157
  } as const;
154
158
 
155
159
  // TEST VERSION
@@ -1,6 +1,6 @@
1
1
  export const PYTH_ENDPOINTS: {
2
- [k in 'mainnet' | 'testnet']: Readonly<string[]>;
2
+ [k in 'mainnet' | 'testnet']: string[];
3
3
  } = {
4
4
  testnet: ['https://hermes-beta.pyth.network'],
5
5
  mainnet: ['https://hermes.pyth.network', 'https://scallop.rpc.p2p.world'],
6
- } as const;
6
+ };
@@ -38,7 +38,7 @@ export class Scallop {
38
38
  public suiKit: SuiKit;
39
39
  public cache: ScallopCache;
40
40
 
41
- private _address: ScallopAddress;
41
+ private address: ScallopAddress;
42
42
 
43
43
  public constructor(
44
44
  params: ScallopParams,
@@ -48,17 +48,17 @@ export class Scallop {
48
48
  this.params = params;
49
49
  this.suiKit = new SuiKit(params);
50
50
  this.cache = new ScallopCache(
51
- cacheOptions ?? DEFAULT_CACHE_OPTIONS,
52
51
  this.suiKit,
52
+ cacheOptions ?? DEFAULT_CACHE_OPTIONS,
53
53
  tokenBucket ??
54
54
  new TokenBucket(DEFAULT_TOKENS_PER_INTERVAL, DEFAULT_INTERVAL_IN_MS)
55
55
  );
56
- this._address = new ScallopAddress(
56
+ this.address = new ScallopAddress(
57
57
  {
58
58
  id: params?.addressesId || ADDRESSES_ID,
59
59
  network: params?.networkType,
60
60
  },
61
- this.cache
61
+ { cache: this.cache }
62
62
  );
63
63
  }
64
64
 
@@ -69,9 +69,9 @@ export class Scallop {
69
69
  * @return Scallop Address.
70
70
  */
71
71
  public async getScallopAddress(id?: string) {
72
- await this._address.read(id);
72
+ await this.address.read(id);
73
73
 
74
- return this._address;
74
+ return this.address;
75
75
  }
76
76
 
77
77
  /**
@@ -80,11 +80,9 @@ export class Scallop {
80
80
  * @return Scallop Builder.
81
81
  */
82
82
  public async createScallopBuilder() {
83
- if (!this._address.getAddresses()) await this._address.read();
83
+ if (!this.address.getAddresses()) await this.address.read();
84
84
  const scallopBuilder = new ScallopBuilder(this.params, {
85
- suiKit: this.suiKit,
86
- address: this._address,
87
- cache: this.cache,
85
+ query: await this.createScallopQuery(),
88
86
  });
89
87
 
90
88
  return scallopBuilder;
@@ -97,10 +95,10 @@ export class Scallop {
97
95
  * @return Scallop Client.
98
96
  */
99
97
  public async createScallopClient(walletAddress?: string) {
100
- if (!this._address.getAddresses()) await this._address.read();
98
+ if (!this.address.getAddresses()) await this.address.read();
101
99
  const scallopClient = new ScallopClient(
102
100
  { ...this.params, walletAddress },
103
- { suiKit: this.suiKit, address: this._address, cache: this.cache }
101
+ { builder: await this.createScallopBuilder() }
104
102
  );
105
103
 
106
104
  return scallopClient;
@@ -112,11 +110,9 @@ export class Scallop {
112
110
  * @return Scallop Query.
113
111
  */
114
112
  public async createScallopQuery() {
115
- if (!this._address.getAddresses()) await this._address.read();
113
+ if (!this.address.getAddresses()) await this.address.read();
116
114
  const scallopQuery = new ScallopQuery(this.params, {
117
- suiKit: this.suiKit,
118
- address: this._address,
119
- cache: this.cache,
115
+ utils: await this.createScallopUtils(),
120
116
  });
121
117
 
122
118
  return scallopQuery;
@@ -141,11 +137,9 @@ export class Scallop {
141
137
  * @return Scallop Utils.
142
138
  */
143
139
  public async createScallopUtils() {
144
- if (!this._address.getAddresses()) await this._address.read();
140
+ if (!this.address.getAddresses()) await this.address.read();
145
141
  const scallopUtils = new ScallopUtils(this.params, {
146
- suiKit: this.suiKit,
147
- address: this._address,
148
- cache: this.cache,
142
+ address: this.address,
149
143
  });
150
144
 
151
145
  return scallopUtils;
@@ -1,9 +1,10 @@
1
1
  import { API_BASE_URL, USE_TEST_ADDRESS } from '../constants';
2
- import type { NetworkType } from '@scallop-io/sui-kit';
2
+ import { SuiKit, type NetworkType } from '@scallop-io/sui-kit';
3
3
  import type {
4
4
  ScallopAddressParams,
5
5
  AddressesInterface,
6
6
  AddressStringPath,
7
+ ScallopAddressInstanceParams,
7
8
  } from '../types';
8
9
  import { ScallopCache } from './scallopCache';
9
10
  import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
@@ -370,11 +371,20 @@ export class ScallopAddress {
370
371
  private _network: NetworkType;
371
372
  private _currentAddresses?: AddressesInterface;
372
373
  private _addressesMap: Map<NetworkType, AddressesInterface>;
373
- private _cache: ScallopCache;
374
+ public cache: ScallopCache;
374
375
 
375
- public constructor(params: ScallopAddressParams, cache?: ScallopCache) {
376
+ public constructor(
377
+ params: ScallopAddressParams,
378
+ instance?: ScallopAddressInstanceParams
379
+ ) {
376
380
  const { id, auth, network } = params;
377
- this._cache = cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS);
381
+ this.cache =
382
+ instance?.cache ??
383
+ new ScallopCache(
384
+ instance?.suiKit ?? new SuiKit({}),
385
+ DEFAULT_CACHE_OPTIONS
386
+ );
387
+
378
388
  this._requestClient = axios.create({
379
389
  baseURL: API_BASE_URL,
380
390
  headers: {
@@ -573,7 +583,7 @@ export class ScallopAddress {
573
583
  public async read(id?: string) {
574
584
  const addressesId = id || this._id || undefined;
575
585
  if (addressesId !== undefined) {
576
- const response = await this._cache.queryClient.fetchQuery({
586
+ const response = await this.cache.queryClient.fetchQuery({
577
587
  queryKey: ['api-getAddresses', addressesId],
578
588
  queryFn: async () => {
579
589
  return await this._requestClient.get(`/addresses/${addressesId}`, {
@@ -9,12 +9,12 @@ import type { SuiTransactionBlockResponse } from '@mysten/sui.js/client';
9
9
  import type { TransactionBlock } from '@mysten/sui.js/transactions';
10
10
  import type { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
11
11
  import type {
12
- ScallopInstanceParams,
13
12
  ScallopBuilderParams,
14
13
  ScallopTxBlock,
15
14
  SupportMarketCoins,
16
15
  SupportAssetCoins,
17
16
  SupportSCoin,
17
+ ScallopBuilderInstanceParams,
18
18
  } from '../types';
19
19
  import { ScallopCache } from './scallopCache';
20
20
  import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
@@ -43,39 +43,43 @@ export class ScallopBuilder {
43
43
 
44
44
  public constructor(
45
45
  params: ScallopBuilderParams,
46
- instance?: ScallopInstanceParams
46
+ instance?: ScallopBuilderInstanceParams
47
47
  ) {
48
- this.params = params;
49
48
  this.suiKit = instance?.suiKit ?? new SuiKit(params);
50
- this.cache =
51
- instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
52
- this.address =
53
- instance?.address ??
54
- new ScallopAddress(
49
+
50
+ this.params = params;
51
+ this.walletAddress = normalizeSuiAddress(
52
+ params?.walletAddress || this.suiKit.currentAddress()
53
+ );
54
+
55
+ if (instance?.query) {
56
+ this.query = instance.query;
57
+ this.utils = this.query.utils;
58
+ this.address = this.utils.address;
59
+ this.cache = this.address.cache;
60
+ } else {
61
+ this.cache = new ScallopCache(this.suiKit, DEFAULT_CACHE_OPTIONS);
62
+ this.address = new ScallopAddress(
55
63
  {
56
64
  id: params?.addressesId || ADDRESSES_ID,
57
65
  network: params?.networkType,
58
66
  },
59
- this.cache
67
+ {
68
+ cache: this.cache,
69
+ }
60
70
  );
61
- this.query =
62
- instance?.query ??
63
- new ScallopQuery(params, {
64
- suiKit: this.suiKit,
71
+ this.utils = new ScallopUtils(this.params, {
65
72
  address: this.address,
66
- cache: this.cache,
67
73
  });
68
- this.utils =
69
- instance?.utils ??
70
- new ScallopUtils(this.params, {
71
- suiKit: this.suiKit,
72
- address: this.address,
73
- query: this.query,
74
- cache: this.cache,
75
- });
76
- this.walletAddress = normalizeSuiAddress(
77
- params?.walletAddress || this.suiKit.currentAddress()
78
- );
74
+ this.query = new ScallopQuery(
75
+ {
76
+ walletAddress: this.walletAddress,
77
+ },
78
+ {
79
+ utils: this.utils,
80
+ }
81
+ );
82
+ }
79
83
  this.isTestnet = params.networkType
80
84
  ? params.networkType === 'testnet'
81
85
  : false;
@@ -46,12 +46,12 @@ type QueryInspectTxnParams = {
46
46
 
47
47
  export class ScallopCache {
48
48
  public readonly queryClient: QueryClient;
49
- public readonly _suiKit?: SuiKit;
49
+ public readonly _suiKit: SuiKit;
50
50
  private tokenBucket: TokenBucket;
51
51
 
52
52
  public constructor(
53
+ suiKit: SuiKit,
53
54
  cacheOptions?: QueryClientConfig,
54
- suiKit?: SuiKit,
55
55
  tokenBucket?: TokenBucket
56
56
  ) {
57
57
  this.queryClient = new QueryClient(cacheOptions ?? DEFAULT_CACHE_OPTIONS);
@@ -15,11 +15,13 @@ import { ScallopQuery } from './scallopQuery';
15
15
  import { ScallopCache } from './scallopCache';
16
16
  import { requireSender } from 'src/utils';
17
17
  import type { SuiTransactionBlockResponse } from '@mysten/sui.js/client';
18
- import type { TransactionObjectArgument } from '@mysten/sui.js/transactions';
18
+ import type {
19
+ TransactionObjectArgument,
20
+ TransactionResult,
21
+ } from '@mysten/sui.js/transactions';
19
22
  import type { SuiObjectArg } from '@scallop-io/sui-kit';
20
23
  import type {
21
24
  ScallopClientFnReturnType,
22
- ScallopInstanceParams,
23
25
  ScallopClientParams,
24
26
  SupportPoolCoins,
25
27
  SupportCollateralCoins,
@@ -29,6 +31,8 @@ import type {
29
31
  SupportBorrowIncentiveCoins,
30
32
  ScallopTxBlock,
31
33
  SupportSCoin,
34
+ ScallopClientVeScaReturnType,
35
+ ScallopClientInstanceParams,
32
36
  } from '../types';
33
37
 
34
38
  /**
@@ -56,48 +60,42 @@ export class ScallopClient {
56
60
 
57
61
  public constructor(
58
62
  params: ScallopClientParams,
59
- instance?: ScallopInstanceParams
63
+ instance?: ScallopClientInstanceParams
60
64
  ) {
61
65
  this.params = params;
62
- this.suiKit = instance?.suiKit ?? new SuiKit(params);
63
- this.cache =
64
- instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
65
- this.address =
66
- instance?.address ??
67
- new ScallopAddress(
66
+ this.suiKit =
67
+ instance?.suiKit ?? instance?.builder?.suiKit ?? new SuiKit(params);
68
+ this.walletAddress = normalizeSuiAddress(
69
+ params?.walletAddress || this.suiKit.currentAddress()
70
+ );
71
+
72
+ if (instance?.builder) {
73
+ this.builder = instance.builder;
74
+ this.query = this.builder.query;
75
+ this.utils = this.query.utils;
76
+ this.address = this.utils.address;
77
+ this.cache = this.address.cache;
78
+ } else {
79
+ this.cache = new ScallopCache(this.suiKit, DEFAULT_CACHE_OPTIONS);
80
+ this.address = new ScallopAddress(
68
81
  {
69
82
  id: params?.addressesId || ADDRESSES_ID,
70
83
  network: params?.networkType,
71
84
  },
72
- this.cache
85
+ {
86
+ cache: this.cache,
87
+ }
73
88
  );
74
- this.query =
75
- instance?.query ??
76
- new ScallopQuery(params, {
77
- suiKit: this.suiKit,
89
+ this.utils = new ScallopUtils(this.params, {
78
90
  address: this.address,
79
- cache: this.cache,
80
91
  });
81
- this.utils =
82
- instance?.utils ??
83
- new ScallopUtils(params, {
84
- suiKit: this.suiKit,
85
- address: this.address,
86
- query: this.query,
87
- cache: this.cache,
92
+ this.query = new ScallopQuery(this.params, {
93
+ utils: this.utils,
88
94
  });
89
- this.builder =
90
- instance?.builder ??
91
- new ScallopBuilder(params, {
92
- suiKit: this.suiKit,
93
- address: this.address,
95
+ this.builder = new ScallopBuilder(this.params, {
94
96
  query: this.query,
95
- utils: this.utils,
96
- cache: this.cache,
97
97
  });
98
- this.walletAddress = normalizeSuiAddress(
99
- params?.walletAddress || this.suiKit.currentAddress()
100
- );
98
+ }
101
99
  }
102
100
 
103
101
  /**
@@ -1077,6 +1075,67 @@ export class ScallopClient {
1077
1075
  }
1078
1076
  }
1079
1077
 
1078
+ /* ==================== VeSCA ==================== */
1079
+ /**
1080
+ * Claim unlocked SCA from all veSCA accounts.
1081
+ */
1082
+ public async claimAllUnlockedSca(): Promise<SuiTransactionBlockResponse>;
1083
+ public async claimAllUnlockedSca<S extends boolean>(
1084
+ sign?: S
1085
+ ): Promise<ScallopClientVeScaReturnType<S>>;
1086
+ public async claimAllUnlockedSca<S extends boolean>(
1087
+ sign: S = true as S
1088
+ ): Promise<ScallopClientVeScaReturnType<S>> {
1089
+ // get all veSca keys
1090
+ const veScaKeys = (
1091
+ (await this.query.getVeScas(this.walletAddress)) ?? []
1092
+ ).map(({ keyObject }) => keyObject);
1093
+ if (veScaKeys.length === 0) {
1094
+ throw new Error('No veSCA found in the wallet');
1095
+ }
1096
+
1097
+ const scaCoins: TransactionResult[] = [];
1098
+ const tx = this.builder.createTxBlock();
1099
+ tx.setSender(this.walletAddress);
1100
+
1101
+ await Promise.all(
1102
+ veScaKeys.map(async (key) => {
1103
+ try {
1104
+ const scaCoin = await tx.redeemScaQuick(key, false);
1105
+ if (!scaCoin) return;
1106
+ scaCoins.push(scaCoin);
1107
+ } catch (e) {
1108
+ // ignore
1109
+ }
1110
+ })
1111
+ );
1112
+
1113
+ if (scaCoins.length === 0) {
1114
+ throw new Error('No unlocked SCA found in the veSCA accounts');
1115
+ }
1116
+
1117
+ if (scaCoins.length > 1) {
1118
+ tx.mergeCoins(scaCoins[0], scaCoins.slice(1));
1119
+ }
1120
+ await this.utils.mergeSimilarCoins(
1121
+ tx,
1122
+ scaCoins[0],
1123
+ 'sca',
1124
+ this.walletAddress
1125
+ );
1126
+
1127
+ if (sign) {
1128
+ return (await this.suiKit.signAndSendTxn(
1129
+ tx
1130
+ )) as ScallopClientVeScaReturnType<S>;
1131
+ } else {
1132
+ return {
1133
+ tx: tx.txBlock,
1134
+ scaCoin: scaCoins[0],
1135
+ } as ScallopClientVeScaReturnType<S>;
1136
+ }
1137
+ }
1138
+
1080
1139
  /* ==================== Other Method ==================== */
1081
1140
 
1082
1141
  /**
@@ -17,11 +17,13 @@ import type {
17
17
  TotalValueLocked,
18
18
  ScallopQueryParams,
19
19
  ScallopParams,
20
- ScallopInstanceParams,
21
20
  BorrowIncentivePoolPoints,
22
21
  SupportBorrowIncentiveRewardCoins,
22
+ ScallopIndexerInstanceParams,
23
23
  } from '../types';
24
24
  import { ScallopCache } from './scallopCache';
25
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
26
+ import { SuiKit } from '@scallop-io/sui-kit';
25
27
 
26
28
  /**
27
29
  * @description
@@ -36,13 +38,18 @@ import { ScallopCache } from './scallopCache';
36
38
  * ```
37
39
  */
38
40
  export class ScallopIndexer {
39
- private readonly _cache: ScallopCache;
41
+ private readonly cache: ScallopCache;
40
42
  public readonly params: ScallopQueryParams;
41
43
  private readonly _requestClient: AxiosInstance;
42
44
 
43
- public constructor(params: ScallopParams, instance?: ScallopInstanceParams) {
45
+ public constructor(
46
+ params: ScallopParams,
47
+ instance?: ScallopIndexerInstanceParams
48
+ ) {
44
49
  this.params = params;
45
- this._cache = instance?.cache ?? new ScallopCache();
50
+ this.cache =
51
+ instance?.cache ??
52
+ new ScallopCache(new SuiKit({}), DEFAULT_CACHE_OPTIONS);
46
53
  this._requestClient = axios.create({
47
54
  baseURL: SDK_API_BASE_URL,
48
55
  headers: {
@@ -59,7 +66,7 @@ export class ScallopIndexer {
59
66
  * @return Market data.
60
67
  */
61
68
  public async getMarket(): Promise<Pick<Market, 'pools' | 'collaterals'>> {
62
- const response = await this._cache.queryClient.fetchQuery({
69
+ const response = await this.cache.queryClient.fetchQuery({
63
70
  queryKey: ['market'],
64
71
  queryFn: async () => {
65
72
  return await this._requestClient.get<{
@@ -137,7 +144,7 @@ export class ScallopIndexer {
137
144
  * @return Spools data.
138
145
  */
139
146
  public async getSpools(): Promise<Required<Spools>> {
140
- const response = await this._cache.queryClient.fetchQuery({
147
+ const response = await this.cache.queryClient.fetchQuery({
141
148
  queryKey: ['spools'],
142
149
  queryFn: async () => {
143
150
  return await this._requestClient.get<{
@@ -175,7 +182,7 @@ export class ScallopIndexer {
175
182
  public async getBorrowIncentivePools(): Promise<
176
183
  Required<BorrowIncentivePools>
177
184
  > {
178
- const response = await this._cache.queryClient.fetchQuery({
185
+ const response = await this.cache.queryClient.fetchQuery({
179
186
  queryKey: ['borrowIncentivePools'],
180
187
  queryFn: async () => {
181
188
  return await this._requestClient.get<{
@@ -237,7 +244,7 @@ export class ScallopIndexer {
237
244
  supplyValueChangeRatio: number;
238
245
  }
239
246
  > {
240
- const response = await this._cache.queryClient.fetchQuery({
247
+ const response = await this.cache.queryClient.fetchQuery({
241
248
  queryKey: ['totalValueLocked'],
242
249
  queryFn: async () => {
243
250
  return await this._requestClient.get<
File without changes