@scallop-io/sui-scallop-sdk 2.0.0 → 2.0.2-switchboard-alpha.1
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/README.md +8 -7
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +30 -28
- package/dist/index.mjs +6 -4
- package/package.json +6 -3
- package/src/builders/oracles/index.ts +16 -15
- package/src/builders/oracles/switchboard.ts +222 -259
- package/src/constants/common.ts +0 -125
- package/src/models/scallop.ts +14 -1
- package/src/models/scallopAddress.ts +1 -1
- package/src/models/scallopBuilder.ts +0 -42
- package/src/models/scallopCache.ts +3 -7
- package/src/models/scallopConstants.ts +3 -1
- package/src/models/scallopQuery.ts +0 -7
- package/src/models/suiKit.ts +19 -4
- package/src/queries/coreQuery.ts +0 -15
- package/src/queries/poolAddressesQuery.ts +0 -2
- package/src/queries/portfolioQuery.ts +0 -2
- package/src/queries/xOracleQuery.ts +0 -10
- package/src/types/builder/core.ts +2 -23
- package/src/types/model.ts +3 -2
- package/src/constants/pyth.ts +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scallop-io/sui-scallop-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-switchboard-alpha.1",
|
|
4
4
|
"description": "Typescript sdk for interacting with Scallop contract on SUI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sui",
|
|
@@ -44,8 +44,9 @@
|
|
|
44
44
|
"@noble/hashes": "^1.3.2",
|
|
45
45
|
"@pythnetwork/price-service-client": "^1.8.2",
|
|
46
46
|
"@pythnetwork/pyth-sui-js": "2.1.0",
|
|
47
|
-
"@scallop-io/sui-kit": "1.3.
|
|
47
|
+
"@scallop-io/sui-kit": "1.3.5",
|
|
48
48
|
"@scure/bip39": "^1.2.1",
|
|
49
|
+
"@switchboard-xyz/sui-sdk": "0.0.22-beta.1",
|
|
49
50
|
"@tanstack/query-core": "5.51.15",
|
|
50
51
|
"axios": "^1.6.0",
|
|
51
52
|
"bech32": "^2.0.0",
|
|
@@ -82,7 +83,7 @@
|
|
|
82
83
|
"peerDependencies": {
|
|
83
84
|
"@mysten/bcs": "^1.2.0",
|
|
84
85
|
"@mysten/sui": "1.3.1",
|
|
85
|
-
"@scallop-io/sui-kit": "1.3.
|
|
86
|
+
"@scallop-io/sui-kit": "1.3.5",
|
|
86
87
|
"bn.js": "^5.2.1"
|
|
87
88
|
},
|
|
88
89
|
"lint-staged": {
|
|
@@ -149,6 +150,8 @@
|
|
|
149
150
|
"scripts": {
|
|
150
151
|
"clean": "rm -rf tsconfig.tsbuildinfo ./dist",
|
|
151
152
|
"build": "pnpm run build:tsup",
|
|
153
|
+
"build-sourcemap": "pnpm run build:sourcemap",
|
|
154
|
+
"build:sourcemap": "tsup ./src/index.ts --format esm,cjs --splitting --minify --treeshake --dts --sourcemap",
|
|
152
155
|
"build:tsup": "tsup ./src/index.ts --format esm,cjs --splitting --minify --treeshake --dts",
|
|
153
156
|
"watch:tsup": "tsup ./src/index.ts --format esm,cjs --clean --splitting --watch",
|
|
154
157
|
"watch:types": "tsc --watch",
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
} from 'src/types';
|
|
10
10
|
import { xOracleList as X_ORACLE_LIST } from 'src/constants';
|
|
11
11
|
import { updatePythPriceFeeds } from './pyth';
|
|
12
|
-
|
|
12
|
+
import { updateSwitchboardAggregators } from './switchboard';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Update the price of the oracle for multiple coin.
|
|
@@ -63,22 +63,23 @@ export const updateOracles = async (
|
|
|
63
63
|
filterAssetCoinNames(assetCoinName, 'pyth')
|
|
64
64
|
);
|
|
65
65
|
if (pythAssetCoinNames.length > 0)
|
|
66
|
-
await updatePythPriceFeeds(builder,
|
|
66
|
+
await updatePythPriceFeeds(builder, pythAssetCoinNames, txBlock);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
if (flattenedRules.has('switchboard')) {
|
|
70
|
+
const switchboardAssetCoinNames = assetCoinNames.filter((assetCoinName) =>
|
|
71
|
+
filterAssetCoinNames(assetCoinName, 'switchboard')
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (switchboardAssetCoinNames.length > 0) {
|
|
75
|
+
await updateSwitchboardAggregators(
|
|
76
|
+
builder,
|
|
77
|
+
switchboardAssetCoinNames,
|
|
78
|
+
txBlock,
|
|
79
|
+
builder.params.switchboardSolanaRpc
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
82
83
|
|
|
83
84
|
// Remove duplicate coin names.
|
|
84
85
|
const updateAssetCoinNames = [...new Set(assetCoinNames)];
|
|
@@ -1,270 +1,233 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
//
|
|
1
|
+
import { ScallopBuilder } from 'src/models';
|
|
2
|
+
import { type SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
|
|
3
|
+
import {
|
|
4
|
+
Aggregator,
|
|
5
|
+
AggregatorData,
|
|
6
|
+
ObjectParsingHelper,
|
|
7
|
+
// suiQueueCache,
|
|
8
|
+
// QueueData,
|
|
9
|
+
SwitchboardClient,
|
|
10
|
+
} from '@switchboard-xyz/sui-sdk';
|
|
11
|
+
import { queryMultipleObjects } from 'src/queries';
|
|
12
|
+
import { SuiParsedData } from '@mysten/sui/client';
|
|
13
|
+
import { toHex } from '@mysten/bcs';
|
|
14
|
+
|
|
15
|
+
const getFieldsFromObject = (
|
|
16
|
+
response: SuiParsedData | null | undefined
|
|
17
|
+
): any => {
|
|
18
|
+
// Check if 'data' and 'content' exist and are of the expected type
|
|
19
|
+
if (response && response.dataType === 'moveObject') {
|
|
20
|
+
// Safely return 'fields' from 'content'
|
|
21
|
+
return response.fields as any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
throw new Error('Invalid response data');
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const parseFeedConfigs = (responses: SuiParsedData[]): AggregatorData[] => {
|
|
28
|
+
return responses.map(getFieldsFromObject).map((aggregatorData) => {
|
|
29
|
+
const currentResult = (aggregatorData.current_result as any).fields;
|
|
30
|
+
const updateState = (aggregatorData.update_state as any).fields;
|
|
31
|
+
|
|
32
|
+
// build the data object
|
|
33
|
+
const data: AggregatorData = {
|
|
34
|
+
id: ObjectParsingHelper.asId(aggregatorData.id),
|
|
35
|
+
authority: ObjectParsingHelper.asString(aggregatorData.authority),
|
|
36
|
+
createdAtMs: ObjectParsingHelper.asNumber(aggregatorData.created_at_ms),
|
|
37
|
+
currentResult: {
|
|
38
|
+
maxResult: ObjectParsingHelper.asBN(currentResult.max_result),
|
|
39
|
+
maxTimestamp: ObjectParsingHelper.asNumber(
|
|
40
|
+
currentResult.max_timestamp_ms
|
|
41
|
+
),
|
|
42
|
+
mean: ObjectParsingHelper.asBN(currentResult.mean),
|
|
43
|
+
minResult: ObjectParsingHelper.asBN(currentResult.min_result),
|
|
44
|
+
minTimestamp: ObjectParsingHelper.asNumber(
|
|
45
|
+
currentResult.min_timestamp_ms
|
|
46
|
+
),
|
|
47
|
+
range: ObjectParsingHelper.asBN(currentResult.range),
|
|
48
|
+
result: ObjectParsingHelper.asBN(currentResult.result),
|
|
49
|
+
stdev: ObjectParsingHelper.asBN(currentResult.stdev),
|
|
50
|
+
},
|
|
51
|
+
feedHash: toHex(
|
|
52
|
+
ObjectParsingHelper.asUint8Array(aggregatorData.feed_hash)
|
|
53
|
+
),
|
|
54
|
+
maxStalenessSeconds: ObjectParsingHelper.asNumber(
|
|
55
|
+
aggregatorData.max_staleness_seconds
|
|
56
|
+
),
|
|
57
|
+
maxVariance: ObjectParsingHelper.asNumber(aggregatorData.max_variance),
|
|
58
|
+
minResponses: ObjectParsingHelper.asNumber(aggregatorData.min_responses),
|
|
59
|
+
minSampleSize: ObjectParsingHelper.asNumber(
|
|
60
|
+
aggregatorData.min_sample_size
|
|
61
|
+
),
|
|
62
|
+
name: ObjectParsingHelper.asString(aggregatorData.name),
|
|
63
|
+
queue: ObjectParsingHelper.asString(aggregatorData.queue),
|
|
64
|
+
updateState: {
|
|
65
|
+
currIdx: ObjectParsingHelper.asNumber(updateState.curr_idx),
|
|
66
|
+
results: updateState.results.map((r: any) => {
|
|
67
|
+
const oracleId = r.fields.oracle;
|
|
68
|
+
const value = ObjectParsingHelper.asBN(r.fields.result.fields);
|
|
69
|
+
const timestamp = parseInt(r.fields.timestamp_ms);
|
|
70
|
+
return {
|
|
71
|
+
oracle: oracleId,
|
|
72
|
+
value,
|
|
73
|
+
timestamp,
|
|
74
|
+
};
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return data;
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// const parseQueueAddresses = async (
|
|
84
|
+
// cache: ScallopCache,
|
|
85
|
+
// queueAddresses: string[]
|
|
86
|
+
// ): Promise<void> => {
|
|
87
|
+
// const queueParsedDatas = (
|
|
88
|
+
// await queryMultipleObjects(cache, queueAddresses)
|
|
89
|
+
// ).map((q) => getFieldsFromObject(q.content));
|
|
90
|
+
|
|
91
|
+
// // Get the existing_oracles table ids
|
|
92
|
+
// const existingOracleTableIds = queueParsedDatas.map((q: any) => {
|
|
93
|
+
// return q.existing_oracles.fields.id.id;
|
|
90
94
|
// });
|
|
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
95
|
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
// await
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
//
|
|
206
|
-
//
|
|
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
|
-
// // );
|
|
96
|
+
// for (let i = 0; i < existingOracleTableIds.length; i++) {
|
|
97
|
+
// const parentId = existingOracleTableIds[i];
|
|
98
|
+
// const queueAddress = queueAddresses[i];
|
|
99
|
+
// const queueResponse = queueParsedDatas[i];
|
|
100
|
+
// const queueCachedData = await suiQueueCache.get(queueAddress);
|
|
101
|
+
// if (queueCachedData) {
|
|
102
|
+
// return queueCachedData;
|
|
103
|
+
// }
|
|
104
|
+
|
|
105
|
+
// let cursor = null;
|
|
106
|
+
// let nextPage = true;
|
|
107
|
+
|
|
108
|
+
// const existingOraclesIds = [];
|
|
109
|
+
// while (nextPage) {
|
|
110
|
+
// const resp = await cache.queryGetDynamicFields({
|
|
111
|
+
// parentId,
|
|
112
|
+
// limit: 25,
|
|
113
|
+
// cursor,
|
|
114
|
+
// });
|
|
115
|
+
|
|
116
|
+
// if (!resp) break;
|
|
117
|
+
// const { nextCursor, data, hasNextPage } = resp;
|
|
118
|
+
// nextPage = hasNextPage;
|
|
119
|
+
// cursor = nextCursor;
|
|
120
|
+
|
|
121
|
+
// existingOraclesIds.push(...data.map((t) => t.objectId));
|
|
122
|
+
// }
|
|
123
|
+
|
|
124
|
+
// const existingOracles = await queryMultipleObjects(
|
|
125
|
+
// cache,
|
|
126
|
+
// existingOraclesIds
|
|
127
|
+
// ).then((res) => {
|
|
128
|
+
// return res.map((t) => {
|
|
129
|
+
// const fields: any = getFieldsFromObject(t.content);
|
|
130
|
+
// return {
|
|
131
|
+
// oracleId: ObjectParsingHelper.asString(fields.value.fields.oracle_id),
|
|
132
|
+
// oracleKey: toBase58(
|
|
133
|
+
// ObjectParsingHelper.asUint8Array(fields.value.fields.oracle_key)
|
|
134
|
+
// ),
|
|
135
|
+
// };
|
|
136
|
+
// });
|
|
137
|
+
// });
|
|
138
|
+
|
|
139
|
+
// const queueData = {
|
|
140
|
+
// authority: ObjectParsingHelper.asString(queueResponse.authority),
|
|
141
|
+
// existingOracles,
|
|
142
|
+
// // get fee number (though encoded as string)
|
|
143
|
+
// fee: ObjectParsingHelper.asNumber(queueResponse.fee),
|
|
144
|
+
|
|
145
|
+
// // fee recipient address
|
|
146
|
+
// feeRecipient: ObjectParsingHelper.asString(queueResponse.fee_recipient),
|
|
147
|
+
|
|
148
|
+
// // accepted fee coin types
|
|
149
|
+
// feeTypes: ObjectParsingHelper.asArray(queueResponse.fee_types).map(
|
|
150
|
+
// (ft: any) => ft.fields.name
|
|
151
|
+
// ),
|
|
223
152
|
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
// // )!;
|
|
153
|
+
// // guardian queue id
|
|
154
|
+
// guardianQueueId: ObjectParsingHelper.asString(
|
|
155
|
+
// queueResponse.guardian_queue_id
|
|
156
|
+
// ),
|
|
229
157
|
|
|
230
|
-
//
|
|
231
|
-
//
|
|
158
|
+
// // queue id
|
|
159
|
+
// id: ObjectParsingHelper.asId(queueResponse.id),
|
|
232
160
|
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
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
|
-
// // });
|
|
161
|
+
// // last queue override ms
|
|
162
|
+
// lastQueueOverrideMs: ObjectParsingHelper.asNumber(
|
|
163
|
+
// queueResponse.last_queue_override_ms
|
|
164
|
+
// ),
|
|
253
165
|
|
|
254
|
-
//
|
|
166
|
+
// // minimum attestations
|
|
167
|
+
// minAttestations: ObjectParsingHelper.asNumber(
|
|
168
|
+
// queueResponse.min_attestations
|
|
169
|
+
// ),
|
|
255
170
|
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
171
|
+
// // queue name
|
|
172
|
+
// name: ObjectParsingHelper.asString(queueResponse.name),
|
|
173
|
+
// oracleValidityLengthMs: ObjectParsingHelper.asNumber(
|
|
174
|
+
// queueResponse.oracle_validity_length_ms
|
|
175
|
+
// ),
|
|
260
176
|
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
// );
|
|
177
|
+
// // get source queue key
|
|
178
|
+
// queueKey: toBase58(
|
|
179
|
+
// ObjectParsingHelper.asUint8Array(queueResponse.queue_key) as Uint8Array
|
|
180
|
+
// ),
|
|
181
|
+
// } as QueueData;
|
|
267
182
|
|
|
268
|
-
//
|
|
183
|
+
// suiQueueCache.set(queueAddress, queueData);
|
|
269
184
|
// }
|
|
270
185
|
// };
|
|
186
|
+
|
|
187
|
+
export const updateSwitchboardAggregators = async (
|
|
188
|
+
builder: ScallopBuilder,
|
|
189
|
+
assetCoinNames: string[],
|
|
190
|
+
txBlock: SuiKitTxBlock,
|
|
191
|
+
solanaRPCUrl: string = 'https://crossbar.switchboard.xyz/rpc/mainnet'
|
|
192
|
+
) => {
|
|
193
|
+
const switchboardClient = new SwitchboardClient(builder.suiKit.client());
|
|
194
|
+
const onDemandAggObjects = await queryMultipleObjects(
|
|
195
|
+
builder.cache,
|
|
196
|
+
await builder.query.getSwitchboardOnDemandAggregatorObjectIds(
|
|
197
|
+
assetCoinNames
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const feedConfigs = parseFeedConfigs(
|
|
202
|
+
onDemandAggObjects.map((t) => t.content) as SuiParsedData[]
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Get queue addresses
|
|
206
|
+
// const queueAddresses = feedConfigs.map((fc) => fc.queue);
|
|
207
|
+
|
|
208
|
+
// await parseQueueAddresses(builder.cache, queueAddresses);
|
|
209
|
+
|
|
210
|
+
for (let idx = 0; idx < assetCoinNames.length; idx++) {
|
|
211
|
+
// console.log({ coinName: assetCoinNames[idx] });
|
|
212
|
+
const switchboardAgg = new Aggregator(
|
|
213
|
+
switchboardClient,
|
|
214
|
+
onDemandAggObjects[idx].objectId
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const { responses, failures } = await switchboardAgg.fetchUpdateTx(
|
|
218
|
+
txBlock.txBlock,
|
|
219
|
+
{
|
|
220
|
+
feedConfigs: feedConfigs[idx],
|
|
221
|
+
solanaRPCUrl,
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
console.log({ responses, failures });
|
|
226
|
+
if (failures.length > 0) {
|
|
227
|
+
throw new Error(
|
|
228
|
+
`Failed to update aggregator for ${assetCoinNames[idx]}: ${failures.join(',')}`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
};
|