@scallop-io/sui-scallop-sdk 0.46.39 → 0.46.40

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.
@@ -401,4 +401,8 @@ export declare class ScallopQuery {
401
401
  * @returns Loyalty program information
402
402
  */
403
403
  getLoyaltyProgramInfos(veScaKey?: string | SuiObjectData): Promise<import("../types").LoyaltyProgramInfo | null>;
404
+ /**
405
+ * Get flashloan fee for specified assets
406
+ */
407
+ getFlashLoanFees(assetCoinNames?: SupportAssetCoins[]): Promise<Record<"eth" | "btc" | "usdc" | "usdt" | "sui" | "apt" | "sol" | "cetus" | "afsui" | "hasui" | "vsui" | "sca", number>>;
404
408
  }
@@ -150,3 +150,10 @@ export declare const getMarketCoinAmounts: (query: ScallopQuery, marketCoinNames
150
150
  * @return Owned market coin amount.
151
151
  */
152
152
  export declare const getMarketCoinAmount: (query: ScallopQuery, marketCoinName: SupportMarketCoins, ownerAddress?: string) => Promise<number>;
153
+ /**
154
+ * Get flashloan fee for specific asset
155
+ * @param query - The Scallop query instance.
156
+ * @param assetNames - Specific an array of support pool coin name.
157
+ * @returns Record of asset name to flashloan fee in decimal
158
+ */
159
+ export declare const getFlashLoanFees: (query: ScallopQuery, assetNames: SupportPoolCoins[]) => Promise<Record<SupportPoolCoins, number>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scallop-io/sui-scallop-sdk",
3
- "version": "0.46.39",
3
+ "version": "0.46.40",
4
4
  "description": "Typescript sdk for interacting with Scallop contract on SUI",
5
5
  "keywords": [
6
6
  "sui",
@@ -0,0 +1,18 @@
1
+ import { OptionalKeys, SupportPoolCoins } from 'src/types';
2
+
3
+ export const FlashLoanFeeObjectMap: OptionalKeys<
4
+ Record<SupportPoolCoins, string>
5
+ > = {
6
+ vsui: '0x0069cddee7a5c0b1d34beb5ef0620f978096525f1830b055f38b110f40d73fbb',
7
+ btc: '0x2078490aa37d8fb42b511e5c95e217cb957d141267e16980bc802d76b42719f7',
8
+ sui: '0x27614284a8f0a699ffd35aae8f2572c937ec76771cb21b0d7930ec4491a76ed4',
9
+ usdt: '0x5b61983a19b5159ca348d291e4b595f42db70ccda32852a2ed85528aa65171e4',
10
+ apt: '0x9d5898edcd1e4abcb044273242293a9d036f6a977bf3fe57ab71f5a87c505ee6',
11
+ afsui: '0xac87fde83d434554ec300c1334c9a622aa5b59e82a04334dc99e1cc1f75d4eae',
12
+ hasui: '0xb9f505d532de1d6c9f3a8522a2d16f2958b75c0ed939d4f80b96f584a2a8ed5e',
13
+ usdc: '0xd241d6a7e44ac11a6689370ed9a98eec389b98b8a6695c61fddede9fa7567b90',
14
+ eth: '0xd252acb058e77877810c1290564e290a8f9fcab5bc9aca2884ede8a38810cf34',
15
+ sca: '0xe04e46471754b6f48d81c549ecfec09de02733715a63bec02364c6ac7c4dd2dc',
16
+ cetus: '0xe65a73d11c31b2d323ad2b9f6b4bb0a3c0df9c1b212eef66c854941186a5ddc7',
17
+ sol: '0xe84bdb35b790fc7bdd1645122ac6ac0fc904531d6772c9e25904fece322c5f34',
18
+ };
@@ -1,3 +1,4 @@
1
1
  export * from './common';
2
2
  export * from './enum';
3
3
  export * from './vesca';
4
+ export * from './flashloan';
@@ -1,5 +1,5 @@
1
1
  import { SuiKit } from '@scallop-io/sui-kit';
2
- import { ADDRESSES_ID, SUPPORT_SPOOLS } from '../constants';
2
+ import { ADDRESSES_ID, SUPPORT_POOLS, SUPPORT_SPOOLS } from '../constants';
3
3
  import {
4
4
  queryMarket,
5
5
  getObligations,
@@ -32,6 +32,7 @@ import {
32
32
  getPythPrices,
33
33
  getVeScaTreasuryInfo,
34
34
  getLoyaltyProgramInformations,
35
+ getFlashLoanFees,
35
36
  } from '../queries';
36
37
  import {
37
38
  ScallopQueryParams,
@@ -593,4 +594,13 @@ export class ScallopQuery {
593
594
  public async getLoyaltyProgramInfos(veScaKey?: string | SuiObjectData) {
594
595
  return await getLoyaltyProgramInformations(this, veScaKey);
595
596
  }
597
+
598
+ /**
599
+ * Get flashloan fee for specified assets
600
+ */
601
+ public async getFlashLoanFees(
602
+ assetCoinNames: SupportAssetCoins[] = [...SUPPORT_POOLS]
603
+ ) {
604
+ return await getFlashLoanFees(this, assetCoinNames);
605
+ }
596
606
  }
@@ -4,6 +4,7 @@ import {
4
4
  PROTOCOL_OBJECT_ID,
5
5
  SUPPORT_COLLATERALS,
6
6
  BORROW_FEE_PROTOCOL_ID,
7
+ FlashLoanFeeObjectMap,
7
8
  } from '../constants';
8
9
  import {
9
10
  parseOriginMarketPoolData,
@@ -875,3 +876,94 @@ export const getMarketCoinAmount = async (
875
876
  });
876
877
  return BigNumber(amount).toNumber();
877
878
  };
879
+
880
+ /**
881
+ * Get flashloan fee for specific asset
882
+ * @param query - The Scallop query instance.
883
+ * @param assetNames - Specific an array of support pool coin name.
884
+ * @returns Record of asset name to flashloan fee in decimal
885
+ */
886
+
887
+ export const getFlashLoanFees = async (
888
+ query: ScallopQuery,
889
+ assetNames: SupportPoolCoins[]
890
+ ): Promise<Record<SupportPoolCoins, number>> => {
891
+ const FEE_RATE = 1e4;
892
+ const missingAssets: SupportPoolCoins[] = [];
893
+
894
+ // create mapping from asset type to asset name
895
+ const assetTypeMap = assetNames.reduce(
896
+ (prev, curr) => {
897
+ const assetType = query.utils.parseCoinType(curr).slice(2);
898
+ prev[assetType] = curr;
899
+ return prev;
900
+ },
901
+ {} as Record<string, SupportPoolCoins>
902
+ );
903
+
904
+ // use the mapped object first
905
+ const objIds = assetNames
906
+ .map((assetName) => {
907
+ if (!FlashLoanFeeObjectMap[assetName]) {
908
+ missingAssets.push(assetName);
909
+ return null;
910
+ } else {
911
+ return FlashLoanFeeObjectMap[assetName];
912
+ }
913
+ })
914
+ .filter((t) => !!t) as string[];
915
+
916
+ const flashloanFeeObjects = await query.cache.queryGetObjects(objIds, {
917
+ showContent: true,
918
+ });
919
+
920
+ if (missingAssets.length > 0) {
921
+ // get market object
922
+ const marketObjectId = query.address.get('core.market');
923
+ const marketObjectRes = await query.cache.queryGetObject(marketObjectId, {
924
+ showContent: true,
925
+ });
926
+ if (marketObjectRes.data?.content?.dataType !== 'moveObject')
927
+ throw new Error('Failed to get market object');
928
+
929
+ // get vault
930
+ const vault = (marketObjectRes.data.content.fields as any).vault;
931
+
932
+ // get vault balance sheet object id
933
+ const flashloanFeesTableId = vault.fields.flash_loan_fees.fields.table
934
+ .fields.id.id as string;
935
+
936
+ // the balance sheet is a VecSet<0x1::type_name::TypeName
937
+ const balanceSheetDynamicFields = await query.cache.queryGetDynamicFields({
938
+ parentId: flashloanFeesTableId,
939
+ limit: 50,
940
+ });
941
+
942
+ // get the dynamic object ids
943
+ const dynamicFieldObjectIds = balanceSheetDynamicFields.data
944
+ .filter((field) => {
945
+ const assetType = (field.name.value as any).name as string;
946
+ return !!assetTypeMap[assetType];
947
+ })
948
+ .map((field) => field.objectId);
949
+
950
+ flashloanFeeObjects.push(
951
+ ...(await query.cache.queryGetObjects(dynamicFieldObjectIds, {
952
+ showContent: true,
953
+ }))
954
+ );
955
+ }
956
+
957
+ return flashloanFeeObjects.reduce(
958
+ (prev, curr) => {
959
+ if (curr.content?.dataType === 'moveObject') {
960
+ const objectFields = curr.content.fields as any;
961
+ const assetType = (curr.content.fields as any).name.fields.name;
962
+ const feeNumerator = +objectFields.value;
963
+ prev[assetTypeMap[assetType]] = feeNumerator / FEE_RATE;
964
+ }
965
+ return prev;
966
+ },
967
+ {} as Record<SupportPoolCoins, number>
968
+ );
969
+ };