@scallop-io/sui-scallop-sdk 0.45.0 → 0.46.0
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/dist/builders/borrowIncentiveBuilder.d.ts +1 -1
- package/dist/builders/referralBuilder.d.ts +12 -0
- package/dist/constants/common.d.ts +1 -1
- package/dist/index.js +532 -278
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +586 -328
- package/dist/index.mjs.map +1 -1
- package/dist/models/scallopCache.d.ts +6 -2
- package/dist/models/scallopQuery.d.ts +26 -28
- package/dist/queries/coreQuery.d.ts +3 -29
- package/dist/queries/index.d.ts +1 -0
- package/dist/queries/priceQuery.d.ts +3 -1
- package/dist/queries/referralQuery.d.ts +7 -0
- package/dist/queries/vescaQuery.d.ts +6 -2
- package/dist/types/address.d.ts +15 -0
- package/dist/types/builder/core.d.ts +2 -0
- package/dist/types/builder/index.d.ts +2 -1
- package/dist/types/builder/referral.d.ts +30 -0
- package/dist/types/builder/vesca.d.ts +1 -0
- package/package.json +7 -6
- package/src/builders/borrowIncentiveBuilder.ts +10 -19
- package/src/builders/coreBuilder.ts +54 -0
- package/src/builders/index.ts +5 -2
- package/src/builders/referralBuilder.ts +178 -0
- package/src/builders/vescaBuilder.ts +8 -6
- package/src/constants/common.ts +9 -2
- package/src/constants/vesca.ts +1 -3
- package/src/models/scallopAddress.ts +63 -19
- package/src/models/scallopCache.ts +42 -2
- package/src/models/scallopQuery.ts +40 -0
- package/src/models/scallopUtils.ts +35 -35
- package/src/queries/borrowIncentiveQuery.ts +2 -5
- package/src/queries/coreQuery.ts +33 -197
- package/src/queries/index.ts +1 -0
- package/src/queries/priceQuery.ts +48 -7
- package/src/queries/referralQuery.ts +27 -0
- package/src/queries/spoolQuery.ts +8 -12
- package/src/queries/vescaQuery.ts +93 -14
- package/src/types/address.ts +15 -0
- package/src/types/builder/core.ts +14 -0
- package/src/types/builder/index.ts +2 -0
- package/src/types/builder/referral.ts +51 -0
- package/src/types/builder/vesca.ts +1 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { ScallopBuilder } from 'src/models';
|
|
2
|
+
import { ScallopTxBlock, SupportCoins, SupportPoolCoins } from 'src/types';
|
|
3
|
+
import {
|
|
4
|
+
SUI_CLOCK_OBJECT_ID,
|
|
5
|
+
SuiTxBlock as SuiKitTxBlock,
|
|
6
|
+
SuiObjectArg,
|
|
7
|
+
TransactionBlock,
|
|
8
|
+
} from '@scallop-io/sui-kit';
|
|
9
|
+
import {
|
|
10
|
+
GenerateReferralNormalMethod,
|
|
11
|
+
GenerateReferralQuickMethod,
|
|
12
|
+
ReferralIds,
|
|
13
|
+
ReferralTxBlock,
|
|
14
|
+
SuiTxBlockWithReferralNormalMethods,
|
|
15
|
+
} from 'src/types/builder/referral';
|
|
16
|
+
import { SUPPORT_POOLS } from 'src/constants';
|
|
17
|
+
import { requireSender } from 'src/utils';
|
|
18
|
+
|
|
19
|
+
const generateReferralNormalMethod: GenerateReferralNormalMethod = ({
|
|
20
|
+
builder,
|
|
21
|
+
txBlock,
|
|
22
|
+
}) => {
|
|
23
|
+
const referralIds: ReferralIds = {
|
|
24
|
+
referralPgkId: builder.address.get('referral.id'),
|
|
25
|
+
referralBindings: builder.address.get('referral.referralBindings'),
|
|
26
|
+
referralRevenuePool: builder.address.get('referral.referralRevenuePool'),
|
|
27
|
+
authorizedWitnessList: builder.address.get(
|
|
28
|
+
'referral.authorizedWitnessList'
|
|
29
|
+
),
|
|
30
|
+
referralTiers: builder.address.get('referral.referralTiers'),
|
|
31
|
+
version: builder.address.get('referral.version'),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const veScaTable = builder.address.get('vesca.table');
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
bindToReferral: (veScaKeyId: string) => {
|
|
38
|
+
return txBlock.moveCall(
|
|
39
|
+
`${referralIds.referralPgkId}::referral_bindings::bind_ve_sca_referrer`,
|
|
40
|
+
[
|
|
41
|
+
referralIds.referralBindings,
|
|
42
|
+
txBlock.pure(veScaKeyId),
|
|
43
|
+
veScaTable,
|
|
44
|
+
SUI_CLOCK_OBJECT_ID,
|
|
45
|
+
],
|
|
46
|
+
[]
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
claimReferralTicket: (poolCoinName: SupportCoins) => {
|
|
50
|
+
const coinType = builder.utils.parseCoinType(poolCoinName);
|
|
51
|
+
return txBlock.moveCall(
|
|
52
|
+
`${referralIds.referralPgkId}::scallop_referral_program::claim_ve_sca_referral_ticket`,
|
|
53
|
+
[
|
|
54
|
+
referralIds.version,
|
|
55
|
+
veScaTable,
|
|
56
|
+
referralIds.referralBindings,
|
|
57
|
+
referralIds.authorizedWitnessList,
|
|
58
|
+
referralIds.referralTiers,
|
|
59
|
+
SUI_CLOCK_OBJECT_ID,
|
|
60
|
+
],
|
|
61
|
+
[coinType]
|
|
62
|
+
);
|
|
63
|
+
},
|
|
64
|
+
burnReferralTicket: (ticket: SuiObjectArg, poolCoinName: SupportCoins) => {
|
|
65
|
+
const coinType = builder.utils.parseCoinType(poolCoinName);
|
|
66
|
+
return txBlock.moveCall(
|
|
67
|
+
`${referralIds.referralPgkId}::scallop_referral_program::burn_ve_sca_referral_ticket`,
|
|
68
|
+
[
|
|
69
|
+
referralIds.version,
|
|
70
|
+
ticket,
|
|
71
|
+
referralIds.referralRevenuePool,
|
|
72
|
+
SUI_CLOCK_OBJECT_ID,
|
|
73
|
+
],
|
|
74
|
+
[coinType]
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
claimReferralRevenue: (
|
|
78
|
+
veScaKey: SuiObjectArg,
|
|
79
|
+
poolCoinName: SupportCoins
|
|
80
|
+
) => {
|
|
81
|
+
const coinType = builder.utils.parseCoinType(poolCoinName);
|
|
82
|
+
return txBlock.moveCall(
|
|
83
|
+
`${referralIds.referralPgkId}::referral_revenue_pool::claim_revenue_with_ve_sca_key`,
|
|
84
|
+
[
|
|
85
|
+
referralIds.version,
|
|
86
|
+
referralIds.referralRevenuePool,
|
|
87
|
+
veScaKey,
|
|
88
|
+
SUI_CLOCK_OBJECT_ID,
|
|
89
|
+
],
|
|
90
|
+
[coinType]
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const generateReferralQuickMethod: GenerateReferralQuickMethod = ({
|
|
97
|
+
builder,
|
|
98
|
+
txBlock,
|
|
99
|
+
}) => {
|
|
100
|
+
return {
|
|
101
|
+
claimReferralRevenueQuick: async (
|
|
102
|
+
veScaKey: SuiObjectArg,
|
|
103
|
+
coinNames: SupportPoolCoins[] = [...SUPPORT_POOLS]
|
|
104
|
+
) => {
|
|
105
|
+
const sender = requireSender(txBlock);
|
|
106
|
+
const objToTransfer: SuiObjectArg[] = [];
|
|
107
|
+
for (const coinName of coinNames) {
|
|
108
|
+
if (coinName === 'sui') {
|
|
109
|
+
const rewardCoin = txBlock.claimReferralRevenue(veScaKey, coinName);
|
|
110
|
+
objToTransfer.push(rewardCoin);
|
|
111
|
+
} else {
|
|
112
|
+
// get the matching user coin if exists
|
|
113
|
+
const coins = await builder.suiKit.suiInteractor.selectCoins(
|
|
114
|
+
sender,
|
|
115
|
+
Infinity,
|
|
116
|
+
builder.utils.parseCoinType(coinName)
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const rewardCoin = txBlock.claimReferralRevenue(veScaKey, coinName);
|
|
120
|
+
if (coins.length > 0) {
|
|
121
|
+
txBlock.mergeCoins(rewardCoin, coins);
|
|
122
|
+
}
|
|
123
|
+
objToTransfer.push(rewardCoin);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (objToTransfer.length > 0) {
|
|
127
|
+
txBlock.transferObjects(objToTransfer, sender);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Create an enhanced transaction block instance for interaction with borrow incentive modules of the Scallop contract.
|
|
135
|
+
*
|
|
136
|
+
* @param builder - Scallop builder instance.
|
|
137
|
+
* @param initTxBlock - Scallop txBlock, txBlock created by SuiKit, or original transaction block.
|
|
138
|
+
* @return Scallop borrow incentive txBlock.
|
|
139
|
+
*/
|
|
140
|
+
export const newReferralTxBlock = (
|
|
141
|
+
builder: ScallopBuilder,
|
|
142
|
+
initTxBlock?: ScallopTxBlock | SuiKitTxBlock | TransactionBlock
|
|
143
|
+
) => {
|
|
144
|
+
const txBlock =
|
|
145
|
+
initTxBlock instanceof TransactionBlock
|
|
146
|
+
? new SuiKitTxBlock(initTxBlock)
|
|
147
|
+
: initTxBlock
|
|
148
|
+
? initTxBlock
|
|
149
|
+
: new SuiKitTxBlock();
|
|
150
|
+
|
|
151
|
+
const normalMethod = generateReferralNormalMethod({
|
|
152
|
+
builder,
|
|
153
|
+
txBlock,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const normalTxBlock = new Proxy(txBlock, {
|
|
157
|
+
get: (target, prop) => {
|
|
158
|
+
if (prop in normalMethod) {
|
|
159
|
+
return Reflect.get(normalMethod, prop);
|
|
160
|
+
}
|
|
161
|
+
return Reflect.get(target, prop);
|
|
162
|
+
},
|
|
163
|
+
}) as SuiTxBlockWithReferralNormalMethods;
|
|
164
|
+
|
|
165
|
+
const quickMethod = generateReferralQuickMethod({
|
|
166
|
+
builder,
|
|
167
|
+
txBlock: normalTxBlock,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
return new Proxy(normalTxBlock, {
|
|
171
|
+
get: (target, prop) => {
|
|
172
|
+
if (prop in quickMethod) {
|
|
173
|
+
return Reflect.get(quickMethod, prop);
|
|
174
|
+
}
|
|
175
|
+
return Reflect.get(target, prop);
|
|
176
|
+
},
|
|
177
|
+
}) as ReferralTxBlock;
|
|
178
|
+
};
|
|
@@ -65,11 +65,7 @@ export const requireVeSca = async (
|
|
|
65
65
|
return undefined;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
return veScas
|
|
69
|
-
(prev, acc) =>
|
|
70
|
-
acc.currentVeScaBalance > prev.currentVeScaBalance ? acc : prev,
|
|
71
|
-
veScas[0]
|
|
72
|
-
); // return veSCA with highest veSCA balance
|
|
68
|
+
return veScas[0]; // return veSCA with highest veSCA balance
|
|
73
69
|
};
|
|
74
70
|
|
|
75
71
|
/**
|
|
@@ -161,6 +157,13 @@ const generateNormalVeScaMethod: GenerateVeScaNormalMethod = ({
|
|
|
161
157
|
[]
|
|
162
158
|
);
|
|
163
159
|
},
|
|
160
|
+
mintEmptyVeSca: () => {
|
|
161
|
+
return txBlock.moveCall(
|
|
162
|
+
`${veScaIds.pkgId}::ve_sca::mint_ve_sca_placeholder_key`,
|
|
163
|
+
[veScaIds.config, veScaIds.table],
|
|
164
|
+
[]
|
|
165
|
+
);
|
|
166
|
+
},
|
|
164
167
|
};
|
|
165
168
|
};
|
|
166
169
|
|
|
@@ -378,7 +381,6 @@ export const newVeScaTxBlock = (
|
|
|
378
381
|
},
|
|
379
382
|
}) as SuiTxBlockWithVeScaNormalMethods;
|
|
380
383
|
|
|
381
|
-
// TODO: Add quickMethod for veSCA
|
|
382
384
|
const quickMethod = generateQuickVeScaMethod({
|
|
383
385
|
builder,
|
|
384
386
|
txBlock: normalTxBlock,
|
package/src/constants/common.ts
CHANGED
|
@@ -3,18 +3,25 @@ export const SDK_API_BASE_URL = 'https://sdk.api.scallop.io';
|
|
|
3
3
|
|
|
4
4
|
export const IS_VE_SCA_TEST = false;
|
|
5
5
|
|
|
6
|
+
// export const ADDRESSES_ID = '';
|
|
6
7
|
export const ADDRESSES_ID = IS_VE_SCA_TEST
|
|
7
|
-
? ('65fb07c39c845425d71d7b18' as const)
|
|
8
|
-
|
|
8
|
+
? // ? ('65fb07c39c845425d71d7b18' as const)
|
|
9
|
+
('65fb07c39c845425d71d7b18' as const)
|
|
10
|
+
: ('664dfe22898c36c159e28bc8' as const);
|
|
11
|
+
// : ('6601955b8b0024600a917079' as const);
|
|
9
12
|
// : ('6462a088a7ace142bb6d7e9b' as const);
|
|
10
13
|
|
|
11
14
|
export const PROTOCOL_OBJECT_ID = IS_VE_SCA_TEST
|
|
12
15
|
? ('0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778' as const)
|
|
13
16
|
: ('0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf' as const);
|
|
17
|
+
// export const PROTOCOL_OBJECT_ID =
|
|
18
|
+
// '0x87ddec2984645dbbe2403a509cc6edf393a43acdba9b77d45da2bcbefcf733c1' as const;
|
|
14
19
|
|
|
15
20
|
export const BORROW_FEE_PROTOCOL_ID = IS_VE_SCA_TEST
|
|
16
21
|
? ('0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778' as const)
|
|
17
22
|
: ('0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da' as const); // test environment
|
|
23
|
+
// export const BORROW_FEE_PROTOCOL_ID =
|
|
24
|
+
// '0x87ddec2984645dbbe2403a509cc6edf393a43acdba9b77d45da2bcbefcf733c1' as const;
|
|
18
25
|
|
|
19
26
|
export const SCA_COIN_TYPE = IS_VE_SCA_TEST
|
|
20
27
|
? (`0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524::sca::SCA` as const)
|
package/src/constants/vesca.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { IS_VE_SCA_TEST } from './common';
|
|
2
|
-
|
|
3
1
|
export const UNLOCK_ROUND_DURATION = 60 * 60 * 24; // 1 days in seconds
|
|
4
|
-
export const MAX_LOCK_ROUNDS: number =
|
|
2
|
+
export const MAX_LOCK_ROUNDS: number = 1460; // 4 years in days (or 9 days for testing)
|
|
5
3
|
export const MAX_LOCK_DURATION: number =
|
|
6
4
|
MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION; // 4 years in seconds
|
|
7
5
|
|
|
@@ -19,6 +19,45 @@ const EMPTY_ADDRESSES: AddressesInterface = {
|
|
|
19
19
|
coinDecimalsRegistry: '',
|
|
20
20
|
obligationAccessStore: '',
|
|
21
21
|
coins: {
|
|
22
|
+
cetus: {
|
|
23
|
+
id: '',
|
|
24
|
+
metaData: '',
|
|
25
|
+
treasury: '',
|
|
26
|
+
oracle: {
|
|
27
|
+
supra: '',
|
|
28
|
+
switchboard: '',
|
|
29
|
+
pyth: {
|
|
30
|
+
feed: '',
|
|
31
|
+
feedObject: '',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
apt: {
|
|
36
|
+
id: '',
|
|
37
|
+
metaData: '',
|
|
38
|
+
treasury: '',
|
|
39
|
+
oracle: {
|
|
40
|
+
supra: '',
|
|
41
|
+
switchboard: '',
|
|
42
|
+
pyth: {
|
|
43
|
+
feed: '',
|
|
44
|
+
feedObject: '',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
sol: {
|
|
49
|
+
id: '',
|
|
50
|
+
metaData: '',
|
|
51
|
+
treasury: '',
|
|
52
|
+
oracle: {
|
|
53
|
+
supra: '',
|
|
54
|
+
switchboard: '',
|
|
55
|
+
pyth: {
|
|
56
|
+
feed: '',
|
|
57
|
+
feedObject: '',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
22
61
|
btc: {
|
|
23
62
|
id: '',
|
|
24
63
|
metaData: '',
|
|
@@ -140,15 +179,8 @@ const EMPTY_ADDRESSES: AddressesInterface = {
|
|
|
140
179
|
oracles: {
|
|
141
180
|
xOracle: '',
|
|
142
181
|
xOracleCap: '',
|
|
143
|
-
supra: {
|
|
144
|
-
|
|
145
|
-
registryCap: '',
|
|
146
|
-
holder: '',
|
|
147
|
-
},
|
|
148
|
-
switchboard: {
|
|
149
|
-
registry: '',
|
|
150
|
-
registryCap: '',
|
|
151
|
-
},
|
|
182
|
+
supra: { registry: '', registryCap: '', holder: '' },
|
|
183
|
+
switchboard: { registry: '', registryCap: '' },
|
|
152
184
|
pyth: {
|
|
153
185
|
registry: '',
|
|
154
186
|
registryCap: '',
|
|
@@ -178,27 +210,25 @@ const EMPTY_ADDRESSES: AddressesInterface = {
|
|
|
178
210
|
id: '',
|
|
179
211
|
upgradeCap: '',
|
|
180
212
|
},
|
|
181
|
-
|
|
213
|
+
protocolWhitelist: {
|
|
182
214
|
id: '',
|
|
183
215
|
upgradeCap: '',
|
|
184
216
|
},
|
|
185
|
-
|
|
217
|
+
query: {
|
|
186
218
|
id: '',
|
|
187
219
|
upgradeCap: '',
|
|
188
220
|
},
|
|
189
|
-
|
|
221
|
+
supra: { id: '', upgradeCap: '' },
|
|
222
|
+
pyth: {
|
|
190
223
|
id: '',
|
|
191
224
|
upgradeCap: '',
|
|
192
225
|
},
|
|
226
|
+
switchboard: { id: '', upgradeCap: '' },
|
|
193
227
|
xOracle: {
|
|
194
228
|
id: '',
|
|
195
229
|
upgradeCap: '',
|
|
196
230
|
},
|
|
197
|
-
|
|
198
|
-
testCoin: {
|
|
199
|
-
id: '',
|
|
200
|
-
upgradeCap: '',
|
|
201
|
-
},
|
|
231
|
+
testCoin: { id: '', upgradeCap: '' },
|
|
202
232
|
},
|
|
203
233
|
},
|
|
204
234
|
spool: {
|
|
@@ -239,26 +269,40 @@ const EMPTY_ADDRESSES: AddressesInterface = {
|
|
|
239
269
|
rewardPoolId: '',
|
|
240
270
|
},
|
|
241
271
|
},
|
|
272
|
+
config: '',
|
|
242
273
|
},
|
|
243
274
|
borrowIncentive: {
|
|
244
275
|
id: '',
|
|
245
276
|
adminCap: '',
|
|
246
277
|
object: '',
|
|
247
278
|
query: '',
|
|
248
|
-
config: '',
|
|
249
279
|
incentivePools: '',
|
|
250
280
|
incentiveAccounts: '',
|
|
281
|
+
config: '',
|
|
251
282
|
},
|
|
252
283
|
vesca: {
|
|
253
284
|
id: '',
|
|
285
|
+
object: '',
|
|
254
286
|
adminCap: '',
|
|
255
287
|
tableId: '',
|
|
256
288
|
table: '',
|
|
257
289
|
treasury: '',
|
|
258
290
|
config: '',
|
|
259
291
|
},
|
|
292
|
+
referral: {
|
|
293
|
+
id: '',
|
|
294
|
+
version: '',
|
|
295
|
+
object: '',
|
|
296
|
+
adminCap: '',
|
|
297
|
+
referralBindings: '',
|
|
298
|
+
bindingTableId: '',
|
|
299
|
+
referralRevenuePool: '',
|
|
300
|
+
revenueTableId: '',
|
|
301
|
+
referralTiers: '',
|
|
302
|
+
tiersTableId: '',
|
|
303
|
+
authorizedWitnessList: '',
|
|
304
|
+
},
|
|
260
305
|
};
|
|
261
|
-
|
|
262
306
|
/**
|
|
263
307
|
* @description
|
|
264
308
|
* It provides methods for managing addresses.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QueryClient, QueryClientConfig } from '@tanstack/query-core';
|
|
2
|
-
import { SuiTxArg, SuiTxBlock } from '@scallop-io/sui-kit';
|
|
2
|
+
import { SuiTxArg, SuiTxBlock, normalizeStructTag } from '@scallop-io/sui-kit';
|
|
3
3
|
import { SuiKit } from '@scallop-io/sui-kit';
|
|
4
4
|
import type {
|
|
5
5
|
SuiObjectResponse,
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
GetDynamicFieldsParams,
|
|
12
12
|
DynamicFieldPage,
|
|
13
13
|
GetDynamicFieldObjectParams,
|
|
14
|
+
GetBalanceParams,
|
|
14
15
|
} from '@mysten/sui.js/client';
|
|
15
16
|
import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
|
|
16
17
|
|
|
@@ -70,7 +71,7 @@ export class ScallopCache {
|
|
|
70
71
|
* @description Cache protocol config call for 60 seconds.
|
|
71
72
|
* @returns Promise<ProtocolConfig>
|
|
72
73
|
*/
|
|
73
|
-
|
|
74
|
+
public async getProtocolConfig() {
|
|
74
75
|
return await this.queryClient.fetchQuery({
|
|
75
76
|
queryKey: ['getProtocolConfig'],
|
|
76
77
|
queryFn: async () => {
|
|
@@ -242,4 +243,43 @@ export class ScallopCache {
|
|
|
242
243
|
},
|
|
243
244
|
});
|
|
244
245
|
}
|
|
246
|
+
|
|
247
|
+
public async queryGetAllCoinBalances(
|
|
248
|
+
owner: string
|
|
249
|
+
): Promise<{ [k: string]: string }> {
|
|
250
|
+
const queryKey = ['getAllCoinBalances', owner];
|
|
251
|
+
return this.queryClient.fetchQuery({
|
|
252
|
+
queryKey,
|
|
253
|
+
queryFn: async () => {
|
|
254
|
+
const allBalances = await this.suiKit
|
|
255
|
+
.client()
|
|
256
|
+
.getAllBalances({ owner });
|
|
257
|
+
return allBalances.reduce(
|
|
258
|
+
(acc, coinBalance) => {
|
|
259
|
+
if (coinBalance.totalBalance !== '0') {
|
|
260
|
+
acc[normalizeStructTag(coinBalance.coinType)] =
|
|
261
|
+
coinBalance.totalBalance;
|
|
262
|
+
}
|
|
263
|
+
return acc;
|
|
264
|
+
},
|
|
265
|
+
{} as { [k: string]: string }
|
|
266
|
+
);
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
public async queryGetCoinBalance(input: GetBalanceParams): Promise<string> {
|
|
272
|
+
const queryKey = ['getCoinBalance', input.owner, input.coinType];
|
|
273
|
+
return this.queryClient.fetchQuery({
|
|
274
|
+
queryKey,
|
|
275
|
+
queryFn: async () => {
|
|
276
|
+
if (!input.coinType) return '0';
|
|
277
|
+
return (
|
|
278
|
+
(await this.queryGetAllCoinBalances(input.owner))[
|
|
279
|
+
normalizeStructTag(input.coinType)
|
|
280
|
+
] ?? '0'
|
|
281
|
+
);
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
}
|
|
245
285
|
}
|
|
@@ -25,8 +25,12 @@ import {
|
|
|
25
25
|
getObligationAccounts,
|
|
26
26
|
getObligationAccount,
|
|
27
27
|
getTotalValueLocked,
|
|
28
|
+
queryVeScaKeyIdFromReferralBindings,
|
|
28
29
|
getBindedObligationId,
|
|
29
30
|
getBindedVeScaKey,
|
|
31
|
+
getVeScas,
|
|
32
|
+
getPythPrices,
|
|
33
|
+
getTotalVeScaTreasuryAmount,
|
|
30
34
|
} from '../queries';
|
|
31
35
|
import {
|
|
32
36
|
ScallopQueryParams,
|
|
@@ -272,6 +276,16 @@ export class ScallopQuery {
|
|
|
272
276
|
return await getPythPrice(this, assetCoinName);
|
|
273
277
|
}
|
|
274
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Get prices from pyth fee object.
|
|
281
|
+
*
|
|
282
|
+
* @param assetCoinNames - Array of supported asset coin names.
|
|
283
|
+
* @return Array of asset coin prices.
|
|
284
|
+
*/
|
|
285
|
+
public async getPricesFromPyth(assetCoinNames: SupportAssetCoins[]) {
|
|
286
|
+
return await getPythPrices(this, assetCoinNames);
|
|
287
|
+
}
|
|
288
|
+
|
|
275
289
|
/* ==================== Spool Query Methods ==================== */
|
|
276
290
|
|
|
277
291
|
/**
|
|
@@ -524,6 +538,32 @@ export class ScallopQuery {
|
|
|
524
538
|
return await getTotalValueLocked(this, indexer);
|
|
525
539
|
}
|
|
526
540
|
|
|
541
|
+
/**
|
|
542
|
+
* Get all veSca from walletAdddress
|
|
543
|
+
* @param walletAddress
|
|
544
|
+
* @returns array of veSca
|
|
545
|
+
*/
|
|
546
|
+
public async getVeScas(walletAddress: string) {
|
|
547
|
+
return await getVeScas(this, walletAddress);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Get total vesca treasury with movecall
|
|
552
|
+
* @returns Promise<string | undefined>
|
|
553
|
+
*/
|
|
554
|
+
public async getTotalVeScaTreasuryAmount() {
|
|
555
|
+
return await getTotalVeScaTreasuryAmount(this);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Return binded veScaKeyId of walletAddress if exist
|
|
560
|
+
* @param walletAddress
|
|
561
|
+
* @returns veScaKeyId
|
|
562
|
+
*/
|
|
563
|
+
public async getVeScaKeyIdFromReferralBindings(walletAddress: string) {
|
|
564
|
+
return await queryVeScaKeyIdFromReferralBindings(this, walletAddress);
|
|
565
|
+
}
|
|
566
|
+
|
|
527
567
|
/**
|
|
528
568
|
* Get binded obligationId from a veScaKey if it exists.
|
|
529
569
|
* @param veScaKey
|
|
@@ -419,9 +419,6 @@ export class ScallopUtils {
|
|
|
419
419
|
);
|
|
420
420
|
|
|
421
421
|
for (const endpoint of endpoints) {
|
|
422
|
-
let hasFailRequest = false;
|
|
423
|
-
const pythConnection = new SuiPriceServiceConnection(endpoint);
|
|
424
|
-
|
|
425
422
|
const priceIds = Array.from(failedRequests.values()).reduce(
|
|
426
423
|
(acc, coinName) => {
|
|
427
424
|
const priceId = this._address.get(
|
|
@@ -433,43 +430,46 @@ export class ScallopUtils {
|
|
|
433
430
|
{} as Record<SupportAssetCoins, string>
|
|
434
431
|
);
|
|
435
432
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
if (feed) {
|
|
446
|
-
const data = parseDataFromPythPriceFeed(feed[0], this._address);
|
|
447
|
-
this._priceMap.set(coinName as SupportAssetCoins, {
|
|
448
|
-
price: data.price,
|
|
449
|
-
publishTime: data.publishTime,
|
|
433
|
+
await Promise.allSettled(
|
|
434
|
+
Object.entries(priceIds).map(async ([coinName, priceId]) => {
|
|
435
|
+
const pythConnection = new SuiPriceServiceConnection(endpoint);
|
|
436
|
+
try {
|
|
437
|
+
const feed = await this._cache.queryClient.fetchQuery({
|
|
438
|
+
queryKey: [priceId],
|
|
439
|
+
queryFn: async () => {
|
|
440
|
+
return await pythConnection.getLatestPriceFeeds([priceId]);
|
|
441
|
+
},
|
|
450
442
|
});
|
|
451
|
-
|
|
443
|
+
if (feed) {
|
|
444
|
+
const data = parseDataFromPythPriceFeed(feed[0], this._address);
|
|
445
|
+
this._priceMap.set(coinName as SupportAssetCoins, {
|
|
446
|
+
price: data.price,
|
|
447
|
+
publishTime: data.publishTime,
|
|
448
|
+
});
|
|
449
|
+
coinPrices[coinName as SupportAssetCoins] = data.price;
|
|
450
|
+
}
|
|
451
|
+
failedRequests.delete(coinName as SupportAssetCoins); // remove success price feed to prevent duplicate request on the next endpoint
|
|
452
|
+
} catch (e) {
|
|
453
|
+
console.warn(
|
|
454
|
+
`Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
|
|
455
|
+
);
|
|
452
456
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
`Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
|
|
457
|
-
);
|
|
458
|
-
hasFailRequest = true;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
if (!hasFailRequest) break;
|
|
457
|
+
})
|
|
458
|
+
);
|
|
459
|
+
if (failedRequests.size === 0) break;
|
|
462
460
|
}
|
|
463
461
|
|
|
464
462
|
if (failedRequests.size > 0) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
463
|
+
await Promise.allSettled(
|
|
464
|
+
Array.from(failedRequests.values()).map(async (coinName) => {
|
|
465
|
+
const price = await this._query.getPriceFromPyth(coinName);
|
|
466
|
+
this._priceMap.set(coinName, {
|
|
467
|
+
price: price,
|
|
468
|
+
publishTime: Date.now(),
|
|
469
|
+
});
|
|
470
|
+
coinPrices[coinName] = price;
|
|
471
|
+
})
|
|
472
|
+
);
|
|
473
473
|
}
|
|
474
474
|
}
|
|
475
475
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { normalizeStructTag } from '@mysten/sui.js/utils';
|
|
2
2
|
import {
|
|
3
|
-
IS_VE_SCA_TEST,
|
|
4
3
|
SUPPORT_BORROW_INCENTIVE_POOLS,
|
|
5
4
|
SUPPORT_BORROW_INCENTIVE_REWARDS,
|
|
6
5
|
} from '../constants';
|
|
@@ -208,9 +207,7 @@ export const getBindedObligationId = async (
|
|
|
208
207
|
): Promise<string | null> => {
|
|
209
208
|
const borrowIncentiveObjectId = query.address.get('borrowIncentive.object');
|
|
210
209
|
const incentivePoolsId = query.address.get('borrowIncentive.incentivePools');
|
|
211
|
-
const
|
|
212
|
-
? '0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8'
|
|
213
|
-
: query.address.get('vesca.id');
|
|
210
|
+
const veScaObjId = query.address.get('vesca.object');
|
|
214
211
|
|
|
215
212
|
const client = query.suiKit.client();
|
|
216
213
|
|
|
@@ -229,7 +226,7 @@ export const getBindedObligationId = async (
|
|
|
229
226
|
.id as string;
|
|
230
227
|
|
|
231
228
|
// check if veSca is inside the bind table
|
|
232
|
-
const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${
|
|
229
|
+
const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaObjId}::ve_sca::VeScaKey>`;
|
|
233
230
|
const veScaBindTableResponse = await client.getDynamicFieldObject({
|
|
234
231
|
parentId: veScaBindTableId,
|
|
235
232
|
name: {
|