@scallop-io/sui-scallop-sdk 2.1.6 → 2.1.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scallop-io/sui-scallop-sdk",
3
- "version": "2.1.6",
3
+ "version": "2.1.8",
4
4
  "description": "Typescript sdk for interacting with Scallop contract on SUI",
5
5
  "keywords": [
6
6
  "sui",
@@ -41,7 +41,7 @@
41
41
  "@mysten/sui": "1.28.2",
42
42
  "@pythnetwork/pyth-sui-js": "2.1.0",
43
43
  "@scallop-io/sui-kit": "1.4.0",
44
- "@tanstack/query-core": "5.51.15",
44
+ "@tanstack/query-core": "5.59.16",
45
45
  "axios": "^1.9.0",
46
46
  "bignumber.js": "^9.1.2",
47
47
  "zod": "^3.23.8"
@@ -490,6 +490,28 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
490
490
  );
491
491
  }
492
492
 
493
+ const [sourceVesca, targetVesca] = await Promise.all([
494
+ getVeSca(builder.utils, sourceKey),
495
+ getVeSca(builder.utils, targetKey),
496
+ ]);
497
+
498
+ if (!sourceVesca || !targetVesca) {
499
+ throw new Error('Source or target veSCA not found');
500
+ }
501
+
502
+ // Extend lock period to the max of both veSca
503
+ if (sourceVesca.unlockAt < targetVesca.unlockAt) {
504
+ txBlock.extendLockPeriod(
505
+ sourceVesca.keyId,
506
+ targetVesca.unlockAt / 1000
507
+ );
508
+ } else if (sourceVesca.unlockAt > targetVesca.unlockAt) {
509
+ txBlock.extendLockPeriod(
510
+ targetVesca.keyId,
511
+ sourceVesca.unlockAt / 1000
512
+ );
513
+ }
514
+
493
515
  return txBlock.mergeVeSca(targetKey, sourceKey);
494
516
  },
495
517
  };
@@ -2,6 +2,7 @@ import { NetworkType } from '@scallop-io/sui-kit';
2
2
  import { API_BASE_URL, queryKeys } from 'src/constants';
3
3
  import { AddressesInterface, AddressStringPath } from 'src/types';
4
4
  import ScallopAxios, { ScallopAxiosParams } from './scallopAxios';
5
+ import { QueryKey } from '@tanstack/query-core';
5
6
 
6
7
  export type ScallopAddressParams = {
7
8
  addressId?: string;
@@ -9,6 +10,9 @@ export type ScallopAddressParams = {
9
10
  auth?: string;
10
11
  network?: NetworkType;
11
12
  forceAddressesInterface?: Partial<Record<NetworkType, AddressesInterface>>;
13
+ defaultValues?: {
14
+ addresses?: Partial<Record<NetworkType, AddressesInterface>>;
15
+ };
12
16
  } & ScallopAxiosParams;
13
17
 
14
18
  const EMPTY_ADDRESSES: AddressesInterface = {
@@ -438,7 +442,7 @@ class ScallopAddress {
438
442
  network: 'mainnet' as NetworkType,
439
443
  } as const;
440
444
 
441
- constructor(params: ScallopAddressParams = {}) {
445
+ constructor(public readonly params: ScallopAddressParams = {}) {
442
446
  this.scallopAxios = new ScallopAxios({
443
447
  ...this.defaultParamValues,
444
448
  baseUrl: params.addressApiUrl || API_BASE_URL,
@@ -484,6 +488,10 @@ class ScallopAddress {
484
488
  return this.axiosClient.queryClient;
485
489
  }
486
490
 
491
+ get defaultValues() {
492
+ return this.params.defaultValues;
493
+ }
494
+
487
495
  getId() {
488
496
  return this.addressId;
489
497
  }
@@ -651,6 +659,23 @@ class ScallopAddress {
651
659
  }
652
660
  }
653
661
 
662
+ protected async readApi<T>({
663
+ url,
664
+ queryKey,
665
+ }: {
666
+ url: string;
667
+ queryKey: QueryKey;
668
+ }) {
669
+ const resp = await this.axiosClient.get<T>(url, queryKey);
670
+ if (resp.status === 200) {
671
+ return resp.data as T;
672
+ } else {
673
+ throw Error(
674
+ `Error: ${resp.status}; Failed to read ${url} ${resp.statusText}`
675
+ );
676
+ }
677
+ }
678
+
654
679
  /**
655
680
  * Read and synchronizes all addresses from the API into instance.
656
681
  *
@@ -660,25 +685,35 @@ class ScallopAddress {
660
685
  async read(id?: string) {
661
686
  const addressId = id || this.addressId || undefined;
662
687
  if (addressId !== undefined) {
663
- const response = await this.axiosClient.get(
664
- `/addresses/${addressId}`,
665
- queryKeys.api.getAddresses({ addressId }) as string[]
666
- );
688
+ const response = await (async () => {
689
+ try {
690
+ return await this.readApi<
691
+ Record<NetworkType, AddressesInterface> & { id?: string }
692
+ >({
693
+ url: `/addresses/${addressId}`,
694
+ queryKey: queryKeys.api.getAddresses({ addressId }) as string[],
695
+ });
696
+ } catch (e) {
697
+ console.error(e);
698
+ return {
699
+ id: '',
700
+ mainnet: this.defaultValues?.addresses?.mainnet ?? EMPTY_ADDRESSES,
701
+ };
702
+ }
703
+ })();
667
704
 
668
- if (response.status === 200) {
669
- for (const [network, addresses] of Object.entries<AddressesInterface>(
670
- response.data
671
- )) {
672
- if (['localnet', 'devnet', 'testnet', 'mainnet'].includes(network)) {
673
- if (network === this.network) this.currentAddresses = addresses;
674
- this.addressMap.set(network as NetworkType, addresses);
675
- }
705
+ const isNetworkValid = (network: string): network is NetworkType =>
706
+ ['localnet', 'devnet', 'testnet', 'mainnet'].includes(network);
707
+
708
+ for (const [network, addresses] of Object.entries(response)) {
709
+ if (isNetworkValid(network) && typeof addresses === 'object') {
710
+ if (network === this.network) this.currentAddresses = addresses;
711
+
712
+ this.addressMap.set(network, addresses);
676
713
  }
677
- this.addressId = response.data.id;
678
- return this.getAllAddresses();
679
- } else {
680
- throw Error('Failed to create addresses.');
681
714
  }
715
+ this.addressId = response.id;
716
+ return this.getAllAddresses();
682
717
  } else {
683
718
  throw Error('Please provide API addresses id.');
684
719
  }
@@ -1,9 +1,7 @@
1
1
  import { PoolAddress, Whitelist } from 'src/types';
2
2
  import ScallopAddress, { ScallopAddressParams } from './scallopAddress';
3
3
  import { NetworkType, parseStructTag } from '@scallop-io/sui-kit';
4
- import ScallopAxios from './scallopAxios';
5
4
  import { queryKeys } from 'src/constants';
6
- import { QueryKey } from '@tanstack/query-core';
7
5
 
8
6
  const isEmptyObject = (obj: object) => {
9
7
  return Object.keys(obj).length === 0;
@@ -29,6 +27,10 @@ export type ScallopConstantsParams = {
29
27
  whitelistApiUrl?: string;
30
28
  forcePoolAddressInterface?: Record<string, PoolAddress>;
31
29
  forceWhitelistInterface?: Whitelist | Record<string, any>;
30
+ defaultValues?: {
31
+ poolAddresses?: Record<string, PoolAddress>;
32
+ whitelist?: Whitelist | Record<string, any>;
33
+ };
32
34
  } & ScallopAddressParams;
33
35
 
34
36
  const DEFAULT_WHITELIST = {
@@ -101,11 +103,8 @@ class ScallopConstants extends ScallopAddress {
101
103
  */
102
104
  public supportedBorrowIncentiveRewards: Set<CoinName> = new Set();
103
105
 
104
- private scallopConstantAxios: ScallopAxios;
105
-
106
106
  constructor(public readonly params: ScallopConstantsParams = {}) {
107
107
  super(params);
108
- this.scallopConstantAxios = new ScallopAxios();
109
108
  }
110
109
 
111
110
  get protocolObjectId() {
@@ -150,6 +149,10 @@ class ScallopConstants extends ScallopAddress {
150
149
  });
151
150
  }
152
151
 
152
+ get defaultValues() {
153
+ return this.params.defaultValues;
154
+ }
155
+
153
156
  private isAddressInitialized({
154
157
  networkType = 'mainnet',
155
158
  }: {
@@ -320,45 +323,43 @@ class ScallopConstants extends ScallopAddress {
320
323
  ]);
321
324
  }
322
325
 
323
- private async readApi<T>({
324
- url,
325
- queryKey,
326
- }: {
327
- url: string;
328
- queryKey: QueryKey;
329
- }) {
330
- const resp = await this.scallopConstantAxios.get<T>(url, queryKey);
331
- if (resp.status === 200) {
332
- return resp.data as T;
333
- } else {
334
- throw Error(
335
- `Error: ${resp.status}; Failed to read ${url} ${resp.statusText}`
336
- );
337
- }
338
- }
339
-
340
326
  async readWhiteList() {
341
- const response = await this.readApi<Record<keyof Whitelist, string[]>>({
342
- url:
343
- this.params.whitelistApiUrl ??
344
- `https://sui.apis.scallop.io/pool/whitelist`,
345
- queryKey: queryKeys.api.getWhiteList(),
346
- });
327
+ const response = await (async () => {
328
+ try {
329
+ return await this.readApi<Record<keyof Whitelist, string[]>>({
330
+ url:
331
+ this.params.whitelistApiUrl ??
332
+ `https://sui.apis.scallop.io/pool/whitelist`,
333
+ queryKey: queryKeys.api.getWhiteList(),
334
+ });
335
+ } catch (e) {
336
+ console.error(e);
337
+ return this.defaultValues?.whitelist ?? DEFAULT_WHITELIST;
338
+ }
339
+ })();
347
340
 
348
341
  return Object.fromEntries(
349
342
  Object.entries(response)
350
- .filter(([_, value]) => Array.isArray(value))
351
- .map(([key, value]) => [key, new Set(value)])
343
+ .filter(([_, value]) => Array.isArray(value) || value instanceof Set)
344
+ .map(([key, value]) => [
345
+ key,
346
+ value instanceof Set ? value : new Set(value),
347
+ ])
352
348
  ) as Whitelist;
353
349
  }
354
350
 
355
351
  async readPoolAddresses() {
356
- return await this.readApi<Record<string, PoolAddress>>({
357
- url:
358
- this.params.poolAddressesApiUrl ??
359
- `https://sui.apis.scallop.io/pool/addresses`,
360
- queryKey: queryKeys.api.getPoolAddresses(),
361
- });
352
+ try {
353
+ return await this.readApi<Record<string, PoolAddress>>({
354
+ url:
355
+ this.params.poolAddressesApiUrl ??
356
+ `https://sui.apis.scallop.io/pool/addresses`,
357
+ queryKey: queryKeys.api.getPoolAddresses(),
358
+ });
359
+ } catch (e) {
360
+ console.error(e);
361
+ return this.defaultValues?.poolAddresses ?? {};
362
+ }
362
363
  }
363
364
  }
364
365
 
@@ -1,6 +1,7 @@
1
1
  import { _SUPPORT_ORACLES, SupportOracleType } from './constant/xOracle';
2
2
 
3
3
  export interface AddressesInterface {
4
+ id?: string;
4
5
  core: {
5
6
  version: string;
6
7
  versionCap: string;