@scallop-io/sui-scallop-sdk 2.2.3-pyth-sponsored-transaction-alpha.2 → 2.2.3-pyth-sponsored-transaction-alpha.3
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 +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +17 -17
- package/dist/index.mjs +4 -4
- package/package.json +3 -2
- package/src/builders/coreBuilder.ts +3 -2
- package/src/builders/oracles/pyth.ts +93 -9
- package/src/constants/testAddress.ts +1 -4
- package/src/models/scallopUtils.ts +4 -2
- package/src/types/builder/core.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scallop-io/sui-scallop-sdk",
|
|
3
|
-
"version": "2.2.3-pyth-sponsored-transaction-alpha.
|
|
3
|
+
"version": "2.2.3-pyth-sponsored-transaction-alpha.3",
|
|
4
4
|
"description": "Typescript sdk for interacting with Scallop contract on SUI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sui",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@mysten/sui": "1.28.2",
|
|
42
|
-
"@pythnetwork/pyth-sui-js": "2.
|
|
42
|
+
"@pythnetwork/pyth-sui-js": "2.2.0",
|
|
43
43
|
"@scallop-io/sui-kit": "1.4.1",
|
|
44
44
|
"@tanstack/query-core": "5.59.16",
|
|
45
45
|
"axios": "^1.9.0",
|
|
@@ -146,6 +146,7 @@
|
|
|
146
146
|
"scripts": {
|
|
147
147
|
"clean": "rm -rf tsconfig.tsbuildinfo ./dist",
|
|
148
148
|
"build": "pnpm run build:tsup",
|
|
149
|
+
"build:sourcemap": "tsup ./src/index.ts --format esm,cjs --sourcemap --dts",
|
|
149
150
|
"build:tsup": "tsup ./src/index.ts --format esm,cjs --splitting --minify --treeshake --dts",
|
|
150
151
|
"watch:tsup": "tsup ./src/index.ts --format esm,cjs --clean --splitting --watch",
|
|
151
152
|
"watch:types": "tsc --watch",
|
|
@@ -313,7 +313,8 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
|
|
|
313
313
|
amount,
|
|
314
314
|
collateralCoinName,
|
|
315
315
|
obligationId,
|
|
316
|
-
obligationKey
|
|
316
|
+
obligationKey,
|
|
317
|
+
isSponsoredTx = false
|
|
317
318
|
) => {
|
|
318
319
|
const obligationInfo = await requireObligationInfo(
|
|
319
320
|
builder,
|
|
@@ -324,7 +325,7 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
|
|
|
324
325
|
const updateCoinNames = await builder.utils.getObligationCoinNames(
|
|
325
326
|
obligationInfo.obligationId
|
|
326
327
|
);
|
|
327
|
-
await updateOracles(builder, txBlock, updateCoinNames);
|
|
328
|
+
await updateOracles(builder, txBlock, updateCoinNames, { isSponsoredTx });
|
|
328
329
|
return txBlock.takeCollateral(
|
|
329
330
|
obligationInfo.obligationId,
|
|
330
331
|
obligationInfo.obligationKey as SuiObjectArg,
|
|
@@ -1,9 +1,82 @@
|
|
|
1
1
|
import {
|
|
2
|
+
HexString,
|
|
2
3
|
SuiPriceServiceConnection,
|
|
3
4
|
SuiPythClient,
|
|
4
5
|
} from '@pythnetwork/pyth-sui-js';
|
|
5
6
|
import { ScallopBuilder } from 'src/models';
|
|
6
|
-
import
|
|
7
|
+
import {
|
|
8
|
+
SUI_CLOCK_OBJECT_ID,
|
|
9
|
+
type SuiTxBlock as SuiKitTxBlock,
|
|
10
|
+
type Transaction,
|
|
11
|
+
} from '@scallop-io/sui-kit';
|
|
12
|
+
import { SuiClient } from '@mysten/sui/client';
|
|
13
|
+
|
|
14
|
+
type ObjectId = string;
|
|
15
|
+
class ScallopPythClient extends SuiPythClient {
|
|
16
|
+
constructor(
|
|
17
|
+
provider: SuiClient,
|
|
18
|
+
pythStateId: ObjectId,
|
|
19
|
+
wormholeStateId: ObjectId,
|
|
20
|
+
private params: {
|
|
21
|
+
// addressId?: string;
|
|
22
|
+
defaultPackageId: ObjectId;
|
|
23
|
+
gasStationId: ObjectId;
|
|
24
|
+
}
|
|
25
|
+
) {
|
|
26
|
+
super(provider, pythStateId, wormholeStateId);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async updatePriceFeedsWithSponsoredBaseUpdateFee(
|
|
30
|
+
tx: Transaction,
|
|
31
|
+
updates: Buffer[],
|
|
32
|
+
feedIds: HexString[]
|
|
33
|
+
) {
|
|
34
|
+
if (!this.params) throw new Error('Please provide params');
|
|
35
|
+
const { defaultPackageId: scallopSponsorPackage, gasStationId } =
|
|
36
|
+
this.params;
|
|
37
|
+
const packageId = await this.getPythPackageId();
|
|
38
|
+
let priceUpdatesHotPotato = await this.verifyVaasAndGetHotPotato(
|
|
39
|
+
tx,
|
|
40
|
+
updates,
|
|
41
|
+
packageId
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const priceInfoObjects = [];
|
|
45
|
+
for (const feedId of feedIds) {
|
|
46
|
+
const priceInfoObjectId = await this.getPriceFeedObjectId(feedId);
|
|
47
|
+
if (!priceInfoObjectId) {
|
|
48
|
+
throw new Error(`Price feed object not found for ID: ${feedId}`);
|
|
49
|
+
}
|
|
50
|
+
priceInfoObjects.push(priceInfoObjectId);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const clockObjectRef = tx.sharedObjectRef({
|
|
54
|
+
objectId: SUI_CLOCK_OBJECT_ID,
|
|
55
|
+
mutable: false,
|
|
56
|
+
initialSharedVersion: '1',
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < priceInfoObjects.length; i++) {
|
|
60
|
+
const priceInfoObjectId = priceInfoObjects[i];
|
|
61
|
+
[priceUpdatesHotPotato] = tx.moveCall({
|
|
62
|
+
target: `${scallopSponsorPackage}::pyth_sponsor::update_single_price_feed_with_sponsor`,
|
|
63
|
+
arguments: [
|
|
64
|
+
tx.object(this.pythStateId),
|
|
65
|
+
priceUpdatesHotPotato,
|
|
66
|
+
tx.object(priceInfoObjectId),
|
|
67
|
+
tx.object(gasStationId),
|
|
68
|
+
clockObjectRef,
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
tx.moveCall({
|
|
74
|
+
target: `${packageId}::hot_potato_vector::destroy`,
|
|
75
|
+
arguments: [priceUpdatesHotPotato],
|
|
76
|
+
typeArguments: [`${packageId}::price_info::PriceInfo`],
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
7
80
|
|
|
8
81
|
export const updatePythPriceFeeds = async (
|
|
9
82
|
builder: ScallopBuilder,
|
|
@@ -11,7 +84,7 @@ export const updatePythPriceFeeds = async (
|
|
|
11
84
|
txBlock: SuiKitTxBlock,
|
|
12
85
|
isSponsoredTx: boolean = false
|
|
13
86
|
) => {
|
|
14
|
-
const pythClient = new
|
|
87
|
+
const pythClient = new ScallopPythClient(
|
|
15
88
|
builder.suiKit.client,
|
|
16
89
|
builder.address.get('core.oracles.pyth.state'),
|
|
17
90
|
builder.address.get('core.oracles.pyth.wormholeState'),
|
|
@@ -30,19 +103,30 @@ export const updatePythPriceFeeds = async (
|
|
|
30
103
|
const endpoints = builder.utils.pythEndpoints ?? [
|
|
31
104
|
...builder.constants.whitelist.pythEndpoints,
|
|
32
105
|
];
|
|
106
|
+
|
|
107
|
+
// get feed object ids
|
|
33
108
|
for (const endpoint of endpoints) {
|
|
34
109
|
try {
|
|
35
110
|
const pythConnection = new SuiPriceServiceConnection(endpoint);
|
|
36
111
|
const priceUpdateData =
|
|
37
112
|
await pythConnection.getPriceFeedsUpdateData(priceIds);
|
|
38
|
-
await pythClient.updatePriceFeeds(
|
|
39
|
-
txBlock.txBlock,
|
|
40
|
-
priceUpdateData,
|
|
41
|
-
priceIds,
|
|
42
|
-
isSponsoredTx
|
|
43
|
-
);
|
|
44
113
|
|
|
45
|
-
|
|
114
|
+
if (isSponsoredTx) {
|
|
115
|
+
// Use gas station to sponsor the baseFeeUpdate
|
|
116
|
+
await pythClient.updatePriceFeedsWithSponsoredBaseUpdateFee(
|
|
117
|
+
txBlock.txBlock,
|
|
118
|
+
priceUpdateData,
|
|
119
|
+
priceIds
|
|
120
|
+
);
|
|
121
|
+
} else {
|
|
122
|
+
await pythClient.updatePriceFeeds(
|
|
123
|
+
txBlock.txBlock,
|
|
124
|
+
priceUpdateData,
|
|
125
|
+
priceIds
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return;
|
|
46
130
|
} catch (e) {
|
|
47
131
|
console.warn(
|
|
48
132
|
`Failed to update price feeds with endpoint ${endpoint}: ${e}`
|
|
@@ -534,10 +534,7 @@ export const WHITELIST = {
|
|
|
534
534
|
suiBridge: new Set(['sbeth', 'sbusdt', 'sbwbtc']),
|
|
535
535
|
wormhole: new Set(['wusdc', 'wusdt', 'weth', 'wbtc', 'wapt', 'wsol']),
|
|
536
536
|
oracles: new Set(['pyth', 'supra', 'switchboard']),
|
|
537
|
-
pythEndpoints: new Set([
|
|
538
|
-
'https://hermes.pyth.network',
|
|
539
|
-
'https://scallop.rpc.p2p.world',
|
|
540
|
-
]),
|
|
537
|
+
pythEndpoints: new Set(['https://hermes.pyth.network']),
|
|
541
538
|
deprecated: new Set(['wapt', 'wusdc', 'wusdt', 'weth', 'wbtc']),
|
|
542
539
|
borrowIncentiveRewards: new Set(['mpoints']),
|
|
543
540
|
rewardsAsPoint: new Set(['mpoints']),
|
|
@@ -31,6 +31,7 @@ class ScallopUtils implements ScallopUtilsInterface {
|
|
|
31
31
|
public pythEndpoints: string[];
|
|
32
32
|
public readonly scallopSuiKit: ScallopSuiKit;
|
|
33
33
|
public readonly constants: ScallopConstants;
|
|
34
|
+
public readonly timeout: number;
|
|
34
35
|
|
|
35
36
|
constructor(params: ScallopUtilsParams = {}) {
|
|
36
37
|
this.constants = params.scallopConstants ?? new ScallopConstants(params);
|
|
@@ -43,8 +44,9 @@ class ScallopUtils implements ScallopUtilsInterface {
|
|
|
43
44
|
|
|
44
45
|
this.pythEndpoints = params.pythEndpoints ?? [
|
|
45
46
|
'https://hermes.pyth.network',
|
|
46
|
-
'https://scallop.rpc.p2p.world',
|
|
47
47
|
];
|
|
48
|
+
|
|
49
|
+
this.timeout = params.axiosTimeout ?? 4000;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
get walletAddress() {
|
|
@@ -539,7 +541,7 @@ class ScallopUtils implements ScallopUtilsInterface {
|
|
|
539
541
|
|
|
540
542
|
const priceIds = priceIdPairs.map(([_, priceId]) => priceId);
|
|
541
543
|
const pythConnection = new SuiPriceServiceConnection(endpoint, {
|
|
542
|
-
timeout:
|
|
544
|
+
timeout: this.timeout,
|
|
543
545
|
});
|
|
544
546
|
|
|
545
547
|
try {
|
|
@@ -93,7 +93,8 @@ export type CoreQuickMethods = {
|
|
|
93
93
|
amount: number,
|
|
94
94
|
collateralCoinName: string,
|
|
95
95
|
obligationId?: SuiObjectArg,
|
|
96
|
-
obligationKey?: SuiObjectArg
|
|
96
|
+
obligationKey?: SuiObjectArg,
|
|
97
|
+
isSponsoredTx?: boolean
|
|
97
98
|
) => Promise<TransactionResult>;
|
|
98
99
|
borrowQuick: (
|
|
99
100
|
amount: number,
|