@scallop-io/sui-scallop-sdk 1.5.3 → 2.0.0-alpha.10
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/index.d.mts +509 -602
- package/dist/index.d.ts +509 -602
- package/dist/index.js +28 -59
- package/dist/index.mjs +7 -7
- package/package.json +1 -1
- package/src/builders/coreBuilder.ts +33 -33
- package/src/builders/loyaltyProgramBuilder.ts +5 -3
- package/src/builders/{oracle.ts → oracles/index.ts} +48 -60
- package/src/builders/oracles/pyth.ts +44 -0
- package/src/builders/oracles/switchboard.ts +270 -0
- package/src/builders/referralBuilder.ts +5 -9
- package/src/builders/sCoinBuilder.ts +9 -8
- package/src/builders/spoolBuilder.ts +4 -6
- package/src/constants/common.ts +114 -126
- package/src/constants/index.ts +0 -5
- package/src/constants/pyth.ts +25 -34
- package/src/constants/queryKeys.ts +2 -0
- package/src/constants/testAddress.ts +36 -487
- package/src/models/index.ts +1 -0
- package/src/models/scallop.ts +23 -19
- package/src/models/scallopAddress.ts +17 -5
- package/src/models/scallopBuilder.ts +36 -41
- package/src/models/scallopCache.ts +3 -3
- package/src/models/scallopClient.ts +93 -98
- package/src/models/scallopConstants.ts +399 -0
- package/src/models/scallopIndexer.ts +11 -24
- package/src/models/scallopQuery.ts +76 -79
- package/src/models/scallopUtils.ts +126 -250
- package/src/queries/borrowIncentiveQuery.ts +25 -58
- package/src/queries/borrowLimitQuery.ts +3 -6
- package/src/queries/coreQuery.ts +98 -114
- package/src/queries/flashloanFeeQuery.ts +86 -0
- package/src/queries/index.ts +1 -0
- package/src/queries/isolatedAssetQuery.ts +12 -11
- package/src/queries/poolAddressesQuery.ts +211 -117
- package/src/queries/portfolioQuery.ts +60 -70
- package/src/queries/priceQuery.ts +16 -22
- package/src/queries/sCoinQuery.ts +15 -16
- package/src/queries/spoolQuery.ts +49 -59
- package/src/queries/supplyLimitQuery.ts +2 -6
- package/src/queries/switchboardQuery.ts +64 -0
- package/src/queries/xOracleQuery.ts +29 -32
- package/src/types/address.ts +21 -19
- package/src/types/builder/borrowIncentive.ts +2 -3
- package/src/types/builder/core.ts +20 -27
- package/src/types/builder/index.ts +1 -2
- package/src/types/builder/referral.ts +4 -8
- package/src/types/builder/sCoin.ts +4 -8
- package/src/types/builder/spool.ts +7 -10
- package/src/types/constant/common.ts +44 -49
- package/src/types/constant/enum.ts +15 -27
- package/src/types/constant/xOracle.ts +3 -2
- package/src/types/model.ts +49 -28
- package/src/types/query/borrowIncentive.ts +7 -24
- package/src/types/query/core.ts +8 -18
- package/src/types/query/portfolio.ts +9 -17
- package/src/types/query/spool.ts +5 -11
- package/src/types/utils.ts +1 -21
- package/src/utils/core.ts +1 -1
- package/src/utils/query.ts +15 -23
- package/src/utils/util.ts +6 -84
- package/src/constants/coinGecko.ts +0 -34
- package/src/constants/enum.ts +0 -268
- package/src/constants/flashloan.ts +0 -18
- package/src/constants/poolAddress.ts +0 -898
- package/src/models/scallopPrice.ts +0 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import { Transaction } from '@mysten/sui/transactions';
|
|
|
2
2
|
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';
|
|
3
3
|
import { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
|
|
4
4
|
import { getObligations } from '../queries';
|
|
5
|
-
import { updateOracles } from './
|
|
5
|
+
import { updateOracles } from './oracles';
|
|
6
6
|
import { requireSender } from '../utils';
|
|
7
7
|
import type { SuiObjectArg, TransactionResult } from '@scallop-io/sui-kit';
|
|
8
8
|
import type { ScallopBuilder } from '../models';
|
|
@@ -361,39 +361,16 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
|
|
|
361
361
|
const sender = requireSender(txBlock);
|
|
362
362
|
const marketCoinName = builder.utils.parseMarketCoinName(poolCoinName);
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const sCoinName = builder.utils.parseSCoinName(poolCoinName);
|
|
367
|
-
if (!sCoinName) throw new Error(`No sCoin for ${poolCoinName}`);
|
|
368
|
-
const {
|
|
369
|
-
leftCoin,
|
|
370
|
-
takeCoin: sCoins,
|
|
371
|
-
totalAmount,
|
|
372
|
-
} = await builder.selectSCoin(txBlock, sCoinName, amount, sender);
|
|
373
|
-
txBlock.transferObjects([leftCoin], sender);
|
|
374
|
-
const marketCoins = txBlock.burnSCoin(sCoinName, sCoins);
|
|
364
|
+
const sCoinName = builder.utils.parseSCoinName(poolCoinName);
|
|
365
|
+
if (!sCoinName) throw new Error(`No sCoin for ${poolCoinName}`);
|
|
375
366
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
txBlock,
|
|
384
|
-
marketCoinName,
|
|
385
|
-
amount,
|
|
386
|
-
sender
|
|
387
|
-
);
|
|
388
|
-
txBlock.transferObjects([leftCoin], sender);
|
|
389
|
-
txBlock.mergeCoins(marketCoins, [walletMarketCoins]);
|
|
390
|
-
}
|
|
391
|
-
} catch (_e) {
|
|
392
|
-
// ignore
|
|
393
|
-
}
|
|
394
|
-
return txBlock.withdraw(marketCoins, poolCoinName);
|
|
395
|
-
} catch (_e) {
|
|
396
|
-
// no sCoin found
|
|
367
|
+
// check if user has sCoin instead of marketCoin
|
|
368
|
+
const {
|
|
369
|
+
leftCoin,
|
|
370
|
+
takeCoin: sCoins,
|
|
371
|
+
totalAmount,
|
|
372
|
+
} = await builder.selectSCoin(txBlock, sCoinName, amount, sender);
|
|
373
|
+
if (totalAmount === 0) {
|
|
397
374
|
const { leftCoin, takeCoin: walletMarketCoins } =
|
|
398
375
|
await builder.selectMarketCoin(
|
|
399
376
|
txBlock,
|
|
@@ -404,6 +381,29 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
|
|
|
404
381
|
txBlock.transferObjects([leftCoin], sender);
|
|
405
382
|
return txBlock.withdraw(walletMarketCoins, poolCoinName);
|
|
406
383
|
}
|
|
384
|
+
|
|
385
|
+
txBlock.transferObjects([leftCoin], sender);
|
|
386
|
+
const marketCoins = txBlock.burnSCoin(sCoinName, sCoins);
|
|
387
|
+
|
|
388
|
+
// check amount
|
|
389
|
+
amount -= totalAmount;
|
|
390
|
+
try {
|
|
391
|
+
if (amount > 0) {
|
|
392
|
+
// sCoin is not enough, try market coin
|
|
393
|
+
const { leftCoin, takeCoin: walletMarketCoins } =
|
|
394
|
+
await builder.selectMarketCoin(
|
|
395
|
+
txBlock,
|
|
396
|
+
marketCoinName,
|
|
397
|
+
amount,
|
|
398
|
+
sender
|
|
399
|
+
);
|
|
400
|
+
txBlock.transferObjects([leftCoin], sender);
|
|
401
|
+
txBlock.mergeCoins(marketCoins, [walletMarketCoins]);
|
|
402
|
+
}
|
|
403
|
+
} catch (_e) {
|
|
404
|
+
// ignore
|
|
405
|
+
}
|
|
406
|
+
return txBlock.withdraw(marketCoins, poolCoinName);
|
|
407
407
|
},
|
|
408
408
|
borrowQuick: async (amount, poolCoinName, obligationId, obligationKey) => {
|
|
409
409
|
const obligationInfo = await requireObligationInfo(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Transaction } from '@mysten/sui/transactions';
|
|
2
2
|
import { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
|
|
3
|
-
import { coinIds } from 'src/constants';
|
|
4
3
|
import { ScallopBuilder } from 'src/models';
|
|
5
4
|
import {
|
|
6
5
|
GenerateLoyaltyProgramNormalMethod,
|
|
@@ -44,13 +43,16 @@ const generateLoyaltyProgramQuickMethod: GenerateLoyaltyProgramQuickMethod = ({
|
|
|
44
43
|
if (!veScaKey) throw new Error(`No veScaKey found for user ${sender}`);
|
|
45
44
|
|
|
46
45
|
// claim the pending reward
|
|
47
|
-
const rewardCoin =
|
|
46
|
+
const rewardCoin = txBlock.claimLoyaltyRevenue(veScaKey);
|
|
48
47
|
|
|
49
48
|
// get existing sca coin to merge with
|
|
49
|
+
const scaCoinType = builder.constants.coinTypes.sca;
|
|
50
|
+
if (!scaCoinType) throw new Error('Coin type sca not found');
|
|
51
|
+
|
|
50
52
|
await builder.utils.mergeSimilarCoins(
|
|
51
53
|
txBlock,
|
|
52
54
|
rewardCoin,
|
|
53
|
-
|
|
55
|
+
scaCoinType,
|
|
54
56
|
requireSender(txBlock)
|
|
55
57
|
);
|
|
56
58
|
txBlock.transferObjects([rewardCoin], sender);
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';
|
|
2
|
-
import {
|
|
3
|
-
SuiPythClient,
|
|
4
|
-
SuiPriceServiceConnection,
|
|
5
|
-
} from '@pythnetwork/pyth-sui-js';
|
|
6
|
-
import { SUPPORT_COLLATERALS, SUPPORT_POOLS } from '../constants';
|
|
7
2
|
import type { TransactionArgument } from '@mysten/sui/transactions';
|
|
8
3
|
import type { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
|
|
9
|
-
import type { ScallopBuilder } from '
|
|
4
|
+
import type { ScallopBuilder } from 'src/models';
|
|
10
5
|
import type {
|
|
11
|
-
SupportAssetCoins,
|
|
12
6
|
SupportOracleType,
|
|
13
7
|
xOracleRules,
|
|
14
8
|
xOracleRuleType,
|
|
15
|
-
} from '
|
|
16
|
-
import { PYTH_ENDPOINTS } from 'src/constants/pyth';
|
|
9
|
+
} from 'src/types';
|
|
17
10
|
import { xOracleList as X_ORACLE_LIST } from 'src/constants';
|
|
11
|
+
import { updatePythPriceFeeds } from './pyth';
|
|
12
|
+
// import { updateSwitchboardAggregators } from './switchboard';
|
|
18
13
|
|
|
19
14
|
/**
|
|
20
15
|
* Update the price of the oracle for multiple coin.
|
|
@@ -27,9 +22,7 @@ import { xOracleList as X_ORACLE_LIST } from 'src/constants';
|
|
|
27
22
|
export const updateOracles = async (
|
|
28
23
|
builder: ScallopBuilder,
|
|
29
24
|
txBlock: SuiKitTxBlock,
|
|
30
|
-
assetCoinNames:
|
|
31
|
-
...new Set([...SUPPORT_POOLS, ...SUPPORT_COLLATERALS]),
|
|
32
|
-
],
|
|
25
|
+
assetCoinNames: string[] = [...builder.constants.whitelist.lending],
|
|
33
26
|
options: {
|
|
34
27
|
usePythPullModel: boolean;
|
|
35
28
|
useOnChainXOracleList: boolean;
|
|
@@ -45,58 +38,52 @@ export const updateOracles = async (
|
|
|
45
38
|
: X_ORACLE_LIST;
|
|
46
39
|
|
|
47
40
|
// const rules: SupportOracleType[] = builder.isTestnet ? ['pyth'] : ['pyth'];
|
|
48
|
-
const flattenedRules
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
),
|
|
55
|
-
];
|
|
41
|
+
const flattenedRules = new Set(
|
|
42
|
+
Object.values(xOracleList).flatMap(({ primary, secondary }) => [
|
|
43
|
+
...primary,
|
|
44
|
+
...secondary,
|
|
45
|
+
])
|
|
46
|
+
);
|
|
56
47
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
48
|
+
const filterAssetCoinNames = (
|
|
49
|
+
assetCoinName: string,
|
|
50
|
+
rule: SupportOracleType
|
|
51
|
+
) => {
|
|
52
|
+
const assetXOracle = xOracleList[assetCoinName];
|
|
53
|
+
return (
|
|
54
|
+
assetXOracle &&
|
|
55
|
+
(assetXOracle.primary.includes(rule) ||
|
|
56
|
+
assetXOracle.secondary.includes(rule))
|
|
65
57
|
);
|
|
58
|
+
};
|
|
66
59
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const priceUpdateData =
|
|
75
|
-
await pythConnection.getPriceFeedsUpdateData(priceIds);
|
|
76
|
-
await pythClient.updatePriceFeeds(
|
|
77
|
-
txBlock.txBlock, // convert txBlock to TransactionBlock because pyth sdk not support new @mysten/sui yet
|
|
78
|
-
priceUpdateData,
|
|
79
|
-
priceIds
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
break;
|
|
83
|
-
} catch (e) {
|
|
84
|
-
console.warn(
|
|
85
|
-
`Failed to update price feeds with endpoint ${endpoint}: ${e}`
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
60
|
+
// Handle Pyth price feed
|
|
61
|
+
if (flattenedRules.has('pyth') && usePythPullModel) {
|
|
62
|
+
const pythAssetCoinNames = assetCoinNames.filter((assetCoinName) =>
|
|
63
|
+
filterAssetCoinNames(assetCoinName, 'pyth')
|
|
64
|
+
);
|
|
65
|
+
if (pythAssetCoinNames.length > 0)
|
|
66
|
+
await updatePythPriceFeeds(builder, assetCoinNames, txBlock);
|
|
89
67
|
}
|
|
90
68
|
|
|
69
|
+
// Handle Switchboard on-demand aggregator
|
|
70
|
+
// if (flattenedRules.has('switchboard')) {
|
|
71
|
+
// const switchboardAssetCoinNames = assetCoinNames.filter((assetCoinName) =>
|
|
72
|
+
// filterAssetCoinNames(assetCoinName, 'switchboard')
|
|
73
|
+
// );
|
|
74
|
+
// if (switchboardAssetCoinNames.length > 0) {
|
|
75
|
+
// await updateSwitchboardAggregators(
|
|
76
|
+
// builder,
|
|
77
|
+
// switchboardAssetCoinNames,
|
|
78
|
+
// txBlock
|
|
79
|
+
// );
|
|
80
|
+
// }
|
|
81
|
+
// }
|
|
82
|
+
|
|
91
83
|
// Remove duplicate coin names.
|
|
92
84
|
const updateAssetCoinNames = [...new Set(assetCoinNames)];
|
|
93
85
|
for (const assetCoinName of updateAssetCoinNames) {
|
|
94
|
-
|
|
95
|
-
builder,
|
|
96
|
-
txBlock,
|
|
97
|
-
assetCoinName,
|
|
98
|
-
xOracleList[assetCoinName]
|
|
99
|
-
);
|
|
86
|
+
updateOracle(builder, txBlock, assetCoinName, xOracleList[assetCoinName]);
|
|
100
87
|
}
|
|
101
88
|
};
|
|
102
89
|
|
|
@@ -107,10 +94,10 @@ export const updateOracles = async (
|
|
|
107
94
|
* @param txBlock - TxBlock created by SuiKit.
|
|
108
95
|
* @param assetCoinName - Specific support asset coin name.
|
|
109
96
|
*/
|
|
110
|
-
const updateOracle =
|
|
97
|
+
const updateOracle = (
|
|
111
98
|
builder: ScallopBuilder,
|
|
112
99
|
txBlock: SuiKitTxBlock,
|
|
113
|
-
assetCoinName:
|
|
100
|
+
assetCoinName: string,
|
|
114
101
|
rules: xOracleRules
|
|
115
102
|
) => {
|
|
116
103
|
const coinType = builder.utils.parseCoinType(assetCoinName);
|
|
@@ -177,7 +164,7 @@ const updatePrice = (
|
|
|
177
164
|
xOracleId,
|
|
178
165
|
coinType
|
|
179
166
|
);
|
|
180
|
-
Object.entries(rules).forEach(([type, rule]: [any,
|
|
167
|
+
Object.entries(rules).forEach(([type, rule]: [any, string[]]) => {
|
|
181
168
|
if (rule.includes('pyth')) {
|
|
182
169
|
updatePythPrice(
|
|
183
170
|
type,
|
|
@@ -338,7 +325,8 @@ const updateSwitchboardPrice = (
|
|
|
338
325
|
coinType: string
|
|
339
326
|
) => {
|
|
340
327
|
txBlock.moveCall(
|
|
341
|
-
`${packageId}::rule::set_price_as_${type}`,
|
|
328
|
+
// `${packageId}::rule::set_price_as_${type}`,
|
|
329
|
+
`${packageId}::rule::set_as_${type}_price`,
|
|
342
330
|
[
|
|
343
331
|
request,
|
|
344
332
|
aggregatorId,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SuiPriceServiceConnection,
|
|
3
|
+
SuiPythClient,
|
|
4
|
+
} from '@pythnetwork/pyth-sui-js';
|
|
5
|
+
import { ScallopBuilder } from 'src/models';
|
|
6
|
+
import type { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
|
|
7
|
+
|
|
8
|
+
export const updatePythPriceFeeds = async (
|
|
9
|
+
builder: ScallopBuilder,
|
|
10
|
+
assetCoinNames: string[],
|
|
11
|
+
txBlock: SuiKitTxBlock
|
|
12
|
+
) => {
|
|
13
|
+
const pythClient = new SuiPythClient(
|
|
14
|
+
builder.suiKit.client(),
|
|
15
|
+
builder.address.get('core.oracles.pyth.state'),
|
|
16
|
+
builder.address.get('core.oracles.pyth.wormholeState')
|
|
17
|
+
);
|
|
18
|
+
const priceIds = assetCoinNames.map((assetCoinName) =>
|
|
19
|
+
builder.address.get(`core.coins.${assetCoinName}.oracle.pyth.feed`)
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// iterate through the endpoints
|
|
23
|
+
const endpoints = builder.params.pythEndpoints ?? [
|
|
24
|
+
...builder.constants.whitelist.pythEndpoints,
|
|
25
|
+
];
|
|
26
|
+
for (const endpoint of endpoints) {
|
|
27
|
+
try {
|
|
28
|
+
const pythConnection = new SuiPriceServiceConnection(endpoint);
|
|
29
|
+
const priceUpdateData =
|
|
30
|
+
await pythConnection.getPriceFeedsUpdateData(priceIds);
|
|
31
|
+
await pythClient.updatePriceFeeds(
|
|
32
|
+
txBlock.txBlock, // convert txBlock to TransactionBlock because pyth sdk not support new @mysten/sui yet
|
|
33
|
+
priceUpdateData,
|
|
34
|
+
priceIds
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
break;
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.warn(
|
|
40
|
+
`Failed to update price feeds with endpoint ${endpoint}: ${e}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// import { ScallopBuilder } from 'src/models';
|
|
2
|
+
// import {
|
|
3
|
+
// // SUI_CLOCK_OBJECT_ID,
|
|
4
|
+
// // SUI_TYPE_ARG,
|
|
5
|
+
// type SuiTxBlock as SuiKitTxBlock,
|
|
6
|
+
// } from '@scallop-io/sui-kit';
|
|
7
|
+
// import {
|
|
8
|
+
// Aggregator,
|
|
9
|
+
// AggregatorData,
|
|
10
|
+
// ObjectParsingHelper,
|
|
11
|
+
// // AggregatorData,
|
|
12
|
+
// // FeedEvalResponse,
|
|
13
|
+
// // ObjectParsingHelper,
|
|
14
|
+
// // Queue,
|
|
15
|
+
// SwitchboardClient,
|
|
16
|
+
// } from '@switchboard-xyz/sui-sdk';
|
|
17
|
+
// import { queryMultipleObjects } from 'src/queries';
|
|
18
|
+
// import { MoveValue, SuiParsedData } from '@mysten/sui/client';
|
|
19
|
+
// import { toHex } from '@mysten/bcs';
|
|
20
|
+
// // import { CrossbarClient, IOracleJob, OracleJob } from '@switchboard-xyz/common';
|
|
21
|
+
// // import axios from 'axios';
|
|
22
|
+
|
|
23
|
+
// const getFieldsFromObject = (
|
|
24
|
+
// response: SuiParsedData
|
|
25
|
+
// ): {
|
|
26
|
+
// [key: string]: MoveValue;
|
|
27
|
+
// } => {
|
|
28
|
+
// // Check if 'data' and 'content' exist and are of the expected type
|
|
29
|
+
// if (response.dataType === 'moveObject') {
|
|
30
|
+
// // Safely return 'fields' from 'content'
|
|
31
|
+
// return response.fields as any;
|
|
32
|
+
// }
|
|
33
|
+
|
|
34
|
+
// throw new Error('Invalid response data');
|
|
35
|
+
// };
|
|
36
|
+
|
|
37
|
+
// const parseFeedConfigs = (responses: SuiParsedData[]): AggregatorData[] => {
|
|
38
|
+
// return responses.map(getFieldsFromObject).map((aggregatorData) => {
|
|
39
|
+
// const currentResult = (aggregatorData.current_result as any).fields;
|
|
40
|
+
// const updateState = (aggregatorData.update_state as any).fields;
|
|
41
|
+
|
|
42
|
+
// // build the data object
|
|
43
|
+
// const data: AggregatorData = {
|
|
44
|
+
// id: ObjectParsingHelper.asId(aggregatorData.id),
|
|
45
|
+
// authority: ObjectParsingHelper.asString(aggregatorData.authority),
|
|
46
|
+
// createdAtMs: ObjectParsingHelper.asNumber(aggregatorData.created_at_ms),
|
|
47
|
+
// currentResult: {
|
|
48
|
+
// maxResult: ObjectParsingHelper.asBN(currentResult.max_result),
|
|
49
|
+
// maxTimestamp: ObjectParsingHelper.asNumber(
|
|
50
|
+
// currentResult.max_timestamp_ms
|
|
51
|
+
// ),
|
|
52
|
+
// mean: ObjectParsingHelper.asBN(currentResult.mean),
|
|
53
|
+
// minResult: ObjectParsingHelper.asBN(currentResult.min_result),
|
|
54
|
+
// minTimestamp: ObjectParsingHelper.asNumber(
|
|
55
|
+
// currentResult.min_timestamp_ms
|
|
56
|
+
// ),
|
|
57
|
+
// range: ObjectParsingHelper.asBN(currentResult.range),
|
|
58
|
+
// result: ObjectParsingHelper.asBN(currentResult.result),
|
|
59
|
+
// stdev: ObjectParsingHelper.asBN(currentResult.stdev),
|
|
60
|
+
// },
|
|
61
|
+
// feedHash: toHex(
|
|
62
|
+
// ObjectParsingHelper.asUint8Array(aggregatorData.feed_hash)
|
|
63
|
+
// ),
|
|
64
|
+
// maxStalenessSeconds: ObjectParsingHelper.asNumber(
|
|
65
|
+
// aggregatorData.max_staleness_seconds
|
|
66
|
+
// ),
|
|
67
|
+
// maxVariance: ObjectParsingHelper.asNumber(aggregatorData.max_variance),
|
|
68
|
+
// minResponses: ObjectParsingHelper.asNumber(aggregatorData.min_responses),
|
|
69
|
+
// minSampleSize: ObjectParsingHelper.asNumber(
|
|
70
|
+
// aggregatorData.min_sample_size
|
|
71
|
+
// ),
|
|
72
|
+
// name: ObjectParsingHelper.asString(aggregatorData.name),
|
|
73
|
+
// queue: ObjectParsingHelper.asString(aggregatorData.queue),
|
|
74
|
+
// updateState: {
|
|
75
|
+
// currIdx: ObjectParsingHelper.asNumber(updateState.curr_idx),
|
|
76
|
+
// results: updateState.results.map((r: any) => {
|
|
77
|
+
// const oracleId = r.fields.oracle;
|
|
78
|
+
// const value = ObjectParsingHelper.asBN(r.fields.result.fields);
|
|
79
|
+
// const timestamp = parseInt(r.fields.timestamp_ms);
|
|
80
|
+
// return {
|
|
81
|
+
// oracle: oracleId,
|
|
82
|
+
// value,
|
|
83
|
+
// timestamp,
|
|
84
|
+
// };
|
|
85
|
+
// }),
|
|
86
|
+
// },
|
|
87
|
+
// };
|
|
88
|
+
|
|
89
|
+
// return data;
|
|
90
|
+
// });
|
|
91
|
+
// };
|
|
92
|
+
|
|
93
|
+
// // const encodeJobs = (jobArray: OracleJob[]) => {
|
|
94
|
+
// // return jobArray.map((job) => serializeOracleJob(job).toString('base64'));
|
|
95
|
+
// // };
|
|
96
|
+
|
|
97
|
+
// // const normalizeOracleJob = (
|
|
98
|
+
// // data: string | IOracleJob | Record<string, any>
|
|
99
|
+
// // ): OracleJob => {
|
|
100
|
+
// // const parseJobObject = (jobData: Record<string, any>) => {
|
|
101
|
+
// // if (!jobData) {
|
|
102
|
+
// // throw new Error(`No job data provided: ${jobData}`);
|
|
103
|
+
// // } else if (!('tasks' in jobData)) {
|
|
104
|
+
// // throw new Error('"tasks" property is required');
|
|
105
|
+
// // } else if (!(Array.isArray(jobData.tasks) && jobData.tasks.length > 0)) {
|
|
106
|
+
// // throw new Error('"tasks" property must be a non-empty array');
|
|
107
|
+
// // }
|
|
108
|
+
// // return OracleJob.fromObject(jobData);
|
|
109
|
+
// // };
|
|
110
|
+
// // const parseJobString = (jobString: string) => {
|
|
111
|
+
// // // Strip comments using regex from https://regex101.com/r/B8WkuX/1
|
|
112
|
+
// // const cleanJson = jobString.replace(
|
|
113
|
+
// // /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/g,
|
|
114
|
+
// // ''
|
|
115
|
+
// // );
|
|
116
|
+
// // return parseJobObject(JSON.parse(cleanJson));
|
|
117
|
+
// // };
|
|
118
|
+
// // return typeof data === 'string' ? parseJobString(data) : parseJobObject(data);
|
|
119
|
+
// // };
|
|
120
|
+
|
|
121
|
+
// // const serializeOracleJob = (
|
|
122
|
+
// // data: string | IOracleJob | Record<string, any>
|
|
123
|
+
// // ): Buffer => {
|
|
124
|
+
// // const job = normalizeOracleJob(data);
|
|
125
|
+
// // return Buffer.from(OracleJob.encodeDelimited(job).finish());
|
|
126
|
+
// // };
|
|
127
|
+
|
|
128
|
+
// // const fetchSignatures = async (
|
|
129
|
+
// // feedConfig: AggregatorData
|
|
130
|
+
// // ): Promise<{
|
|
131
|
+
// // responses: FeedEvalResponse[];
|
|
132
|
+
// // failures: string[];
|
|
133
|
+
// // }> => {
|
|
134
|
+
// // const crossbarClient = new CrossbarClient('https://crossbar.switchboard.xyz');
|
|
135
|
+
|
|
136
|
+
// // const jobs: OracleJob[] = await crossbarClient
|
|
137
|
+
// // .fetch(feedConfig.feedHash)
|
|
138
|
+
// // .then((res) => res.jobs.map((job) => OracleJob.fromObject(job)));
|
|
139
|
+
|
|
140
|
+
// // const encodedJobs = encodeJobs(jobs);
|
|
141
|
+
// // const maxVariance = Math.floor(feedConfig.maxVariance / 1e9) * 1e9;
|
|
142
|
+
// // const minResponses = feedConfig.minResponses;
|
|
143
|
+
// // const numSignatures = feedConfig.minSampleSize;
|
|
144
|
+
// // const recentHash = toBase58(new Uint8Array(32));
|
|
145
|
+
// // const useTimestamp = true;
|
|
146
|
+
|
|
147
|
+
// // const GATEWAY_URL = 'https://api.mainnet-beta.solana.com';
|
|
148
|
+
// // const TIMEOUT = 10000;
|
|
149
|
+
// // const url = `${GATEWAY_URL}/gateway/api/v1/fetch_signatures`;
|
|
150
|
+
// // const headers = { 'Content-Type': 'application/json' };
|
|
151
|
+
|
|
152
|
+
// // const body = JSON.stringify({
|
|
153
|
+
// // api_version: '1.0.0',
|
|
154
|
+
// // jobs_b64_encoded: encodedJobs,
|
|
155
|
+
// // recent_chainhash: recentHash,
|
|
156
|
+
// // signature_scheme: 'Secp256k1',
|
|
157
|
+
// // hash_scheme: 'Sha256',
|
|
158
|
+
// // num_oracles: numSignatures,
|
|
159
|
+
// // max_variance: maxVariance,
|
|
160
|
+
// // min_responses: minResponses,
|
|
161
|
+
// // use_timestamp: useTimestamp,
|
|
162
|
+
// // });
|
|
163
|
+
|
|
164
|
+
// // return await axios
|
|
165
|
+
// // .post(url, body, {
|
|
166
|
+
// // headers,
|
|
167
|
+
// // timeout: TIMEOUT,
|
|
168
|
+
// // })
|
|
169
|
+
// // .then((r) => r.data);
|
|
170
|
+
// // };
|
|
171
|
+
|
|
172
|
+
// export const updateSwitchboardAggregators = async (
|
|
173
|
+
// builder: ScallopBuilder,
|
|
174
|
+
// assetCoinNames: string[],
|
|
175
|
+
// txBlock: SuiKitTxBlock
|
|
176
|
+
// ) => {
|
|
177
|
+
// const switchboardClient = new SwitchboardClient(builder.suiKit.client());
|
|
178
|
+
// const onDemandAggObjects = await queryMultipleObjects(
|
|
179
|
+
// builder.cache,
|
|
180
|
+
// await builder.query.getSwitchboardOnDemandAggregatorObjectIds(
|
|
181
|
+
// assetCoinNames
|
|
182
|
+
// )
|
|
183
|
+
// );
|
|
184
|
+
|
|
185
|
+
// const feedConfigs = parseFeedConfigs(
|
|
186
|
+
// onDemandAggObjects.map((t) => t.content) as SuiParsedData[]
|
|
187
|
+
// );
|
|
188
|
+
|
|
189
|
+
// for (const idx in assetCoinNames) {
|
|
190
|
+
// // const { switchboardAddress, oracleQueueId } =
|
|
191
|
+
// // await switchboardClient.fetchState();
|
|
192
|
+
|
|
193
|
+
// // const feedConfig = feedConfigs[idx];
|
|
194
|
+
|
|
195
|
+
// // const suiQueue = await new Queue(
|
|
196
|
+
// // switchboardClient,
|
|
197
|
+
// // oracleQueueId
|
|
198
|
+
// // ).loadData();
|
|
199
|
+
|
|
200
|
+
// // const { responses, failures } = await fetchSignatures(feedConfig);
|
|
201
|
+
// // const validOracles = new Set(
|
|
202
|
+
// // suiQueue.existingOracles.map((o) => o.oracleKey)
|
|
203
|
+
// // );
|
|
204
|
+
|
|
205
|
+
// // const validResponses = responses.filter((r) => {
|
|
206
|
+
// // return validOracles.has(toBase58(fromHex(r.oracle_pubkey)));
|
|
207
|
+
// // });
|
|
208
|
+
|
|
209
|
+
// // // if we have no valid responses (or not enough), fail out
|
|
210
|
+
// // if (
|
|
211
|
+
// // !validResponses.length ||
|
|
212
|
+
// // validResponses.length < feedConfig.minSampleSize
|
|
213
|
+
// // ) {
|
|
214
|
+
// // // maybe retry by recursing into the same function / add a retry count
|
|
215
|
+
// // throw new Error('Not enough valid oracle responses.');
|
|
216
|
+
// // }
|
|
217
|
+
|
|
218
|
+
// // // split the gas coin into the right amount for each response
|
|
219
|
+
// // const coins = txBlock.splitCoins(
|
|
220
|
+
// // txBlock.gas,
|
|
221
|
+
// // validResponses.map(() => suiQueue.fee)
|
|
222
|
+
// // );
|
|
223
|
+
|
|
224
|
+
// // // map the responses into the tx
|
|
225
|
+
// // validResponses.forEach((response, i) => {
|
|
226
|
+
// // const oracle = suiQueue.existingOracles.find(
|
|
227
|
+
// // (o) => o.oracleKey === toBase58(fromHex(response.oracle_pubkey))
|
|
228
|
+
// // )!;
|
|
229
|
+
|
|
230
|
+
// // const signature = Array.from(fromBase64(response.signature));
|
|
231
|
+
// // signature.push(response.recovery_id);
|
|
232
|
+
|
|
233
|
+
// // txBlock.moveCall(
|
|
234
|
+
// // `${switchboardAddress}::aggregator_submit_result_action::run`,
|
|
235
|
+
// // [
|
|
236
|
+
// // txBlock.object(onDemandAggObjects[idx].objectId),
|
|
237
|
+
// // txBlock.object(suiQueue.id),
|
|
238
|
+
// // txBlock.pure.u128(response.success_value),
|
|
239
|
+
// // txBlock.pure.bool(response.success_value.startsWith('-')),
|
|
240
|
+
// // txBlock.pure.u64(response.timestamp!),
|
|
241
|
+
// // txBlock.object(oracle.oracleId),
|
|
242
|
+
// // txBlock.pure.vector('u8', signature),
|
|
243
|
+
// // txBlock.sharedObjectRef({
|
|
244
|
+
// // objectId: SUI_CLOCK_OBJECT_ID,
|
|
245
|
+
// // initialSharedVersion: '1',
|
|
246
|
+
// // mutable: false,
|
|
247
|
+
// // }),
|
|
248
|
+
// // coins[i],
|
|
249
|
+
// // ],
|
|
250
|
+
// // [SUI_TYPE_ARG]
|
|
251
|
+
// // );
|
|
252
|
+
// // });
|
|
253
|
+
|
|
254
|
+
// // return { responses, failures };
|
|
255
|
+
|
|
256
|
+
// const switchboardAgg = new Aggregator(
|
|
257
|
+
// switchboardClient,
|
|
258
|
+
// onDemandAggObjects[idx].objectId
|
|
259
|
+
// );
|
|
260
|
+
|
|
261
|
+
// const { responses, failures } = await switchboardAgg.fetchUpdateTx(
|
|
262
|
+
// txBlock.txBlock,
|
|
263
|
+
// {
|
|
264
|
+
// feedConfigs: feedConfigs[idx],
|
|
265
|
+
// }
|
|
266
|
+
// );
|
|
267
|
+
|
|
268
|
+
// return { responses, failures };
|
|
269
|
+
// }
|
|
270
|
+
// };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ScallopBuilder } from 'src/models';
|
|
2
|
-
import { ScallopTxBlock
|
|
2
|
+
import { ScallopTxBlock } from 'src/types';
|
|
3
3
|
import {
|
|
4
4
|
SUI_CLOCK_OBJECT_ID,
|
|
5
5
|
SuiTxBlock as SuiKitTxBlock,
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
ReferralTxBlock,
|
|
14
14
|
SuiTxBlockWithReferralNormalMethods,
|
|
15
15
|
} from 'src/types/builder/referral';
|
|
16
|
-
import { SUPPORT_POOLS } from 'src/constants';
|
|
17
16
|
import { requireSender } from 'src/utils';
|
|
18
17
|
|
|
19
18
|
const generateReferralNormalMethod: GenerateReferralNormalMethod = ({
|
|
@@ -52,7 +51,7 @@ const generateReferralNormalMethod: GenerateReferralNormalMethod = ({
|
|
|
52
51
|
[]
|
|
53
52
|
);
|
|
54
53
|
},
|
|
55
|
-
claimReferralTicket: (poolCoinName:
|
|
54
|
+
claimReferralTicket: (poolCoinName: string) => {
|
|
56
55
|
const coinType = builder.utils.parseCoinType(poolCoinName);
|
|
57
56
|
return builder.moveCall(
|
|
58
57
|
txBlock,
|
|
@@ -68,7 +67,7 @@ const generateReferralNormalMethod: GenerateReferralNormalMethod = ({
|
|
|
68
67
|
[coinType]
|
|
69
68
|
);
|
|
70
69
|
},
|
|
71
|
-
burnReferralTicket: (ticket: SuiObjectArg, poolCoinName:
|
|
70
|
+
burnReferralTicket: (ticket: SuiObjectArg, poolCoinName: string) => {
|
|
72
71
|
const coinType = builder.utils.parseCoinType(poolCoinName);
|
|
73
72
|
builder.moveCall(
|
|
74
73
|
txBlock,
|
|
@@ -82,10 +81,7 @@ const generateReferralNormalMethod: GenerateReferralNormalMethod = ({
|
|
|
82
81
|
[coinType]
|
|
83
82
|
);
|
|
84
83
|
},
|
|
85
|
-
claimReferralRevenue: (
|
|
86
|
-
veScaKey: SuiObjectArg,
|
|
87
|
-
poolCoinName: SupportCoins
|
|
88
|
-
) => {
|
|
84
|
+
claimReferralRevenue: (veScaKey: SuiObjectArg, poolCoinName: string) => {
|
|
89
85
|
const coinType = builder.utils.parseCoinType(poolCoinName);
|
|
90
86
|
return builder.moveCall(
|
|
91
87
|
txBlock,
|
|
@@ -109,7 +105,7 @@ const generateReferralQuickMethod: GenerateReferralQuickMethod = ({
|
|
|
109
105
|
return {
|
|
110
106
|
claimReferralRevenueQuick: async (
|
|
111
107
|
veScaKey: SuiObjectArg,
|
|
112
|
-
coinNames:
|
|
108
|
+
coinNames: string[] = [...builder.constants.whitelist.lending]
|
|
113
109
|
) => {
|
|
114
110
|
const sender = requireSender(txBlock);
|
|
115
111
|
const objToTransfer: SuiObjectArg[] = [];
|