@@ -10,6 +10,7 @@ import {
10
10
import { Chain , SuiChain } from "../chains" ;
11
11
import { DataSource } from "xc_admin_common" ;
12
12
import { Contract } from "../base" ;
13
+ import { SuiPythClient } from "@pythnetwork/pyth-sui-js" ;
13
14
14
15
export class SuiContract extends Contract {
15
16
static type = "SuiContract" ;
@@ -59,27 +60,8 @@ export class SuiContract extends Contract {
59
60
* @param objectId
60
61
*/
61
62
async getPackageId ( objectId : ObjectId ) : Promise < ObjectId > {
62
- const provider = this . getProvider ( ) ;
63
- const state = await provider
64
- . getObject ( {
65
- id : objectId ,
66
- options : {
67
- showContent : true ,
68
- } ,
69
- } )
70
- . then ( ( result ) => {
71
- if ( result . data ?. content ?. dataType == "moveObject" ) {
72
- return result . data . content . fields ;
73
- }
74
-
75
- throw new Error ( "not move object" ) ;
76
- } ) ;
77
-
78
- if ( "upgrade_cap" in state ) {
79
- return state . upgrade_cap . fields . package ;
80
- }
81
-
82
- throw new Error ( "upgrade_cap not found" ) ;
63
+ const client = this . getSdkClient ( ) ;
64
+ return client . getPackageId ( objectId ) ;
83
65
}
84
66
85
67
async getPythPackageId ( ) : Promise < ObjectId > {
@@ -132,7 +114,7 @@ export class SuiContract extends Contract {
132
114
} ;
133
115
}
134
116
135
- async getPriceFeed ( feedId : string ) {
117
+ async getPriceFeedObjectId ( feedId : string ) : Promise < ObjectId | undefined > {
136
118
const tableId = await this . getPriceTableId ( ) ;
137
119
const provider = this . getProvider ( ) ;
138
120
let result = await provider . getDynamicFieldObject ( {
@@ -150,7 +132,13 @@ export class SuiContract extends Contract {
150
132
if ( result . data . content . dataType !== "moveObject" ) {
151
133
throw new Error ( "Price feed type mismatch" ) ;
152
134
}
153
- let priceInfoObjectId = result . data . content . fields . value ;
135
+ return result . data . content . fields . value ;
136
+ }
137
+
138
+ async getPriceFeed ( feedId : string ) {
139
+ const provider = this . getProvider ( ) ;
140
+ let priceInfoObjectId = await this . getPriceFeedObjectId ( feedId ) ;
141
+ if ( ! priceInfoObjectId ) return undefined ;
154
142
let priceInfo = await provider . getObject ( {
155
143
id : priceInfoObjectId ,
156
144
options : { showContent : true } ,
@@ -185,18 +173,60 @@ export class SuiContract extends Contract {
185
173
async executeMigrateInstruction ( vaa : Buffer , keypair : Ed25519Keypair ) {
186
174
const tx = new TransactionBlock ( ) ;
187
175
const packageId = await this . getPythPackageId ( ) ;
188
- let decreeReceipt = await this . getVaaDecreeReceipt ( tx , packageId , vaa ) ;
176
+ let verificationReceipt = await this . getVaaVerificationReceipt (
177
+ tx ,
178
+ packageId ,
179
+ vaa
180
+ ) ;
189
181
190
182
tx . moveCall ( {
191
183
target : `${ packageId } ::migrate::migrate` ,
192
- arguments : [ tx . object ( this . stateId ) , decreeReceipt ] ,
184
+ arguments : [ tx . object ( this . stateId ) , verificationReceipt ] ,
193
185
} ) ;
194
186
195
187
return this . executeTransaction ( tx , keypair ) ;
196
188
}
197
189
198
190
async executeUpdatePriceFeed ( senderPrivateKey : string , vaas : Buffer [ ] ) {
199
- throw new Error ( "Not implemented" ) ;
191
+ // We need the feed ids to be able to execute the transaction
192
+ // it may be possible to get them from the VAA but in batch transactions,
193
+ // it is also possible to hava fewer feeds that user wants to update compared to
194
+ // what exists in the VAA.
195
+ throw new Error ( "Use executeUpdatePriceFeedWithFeeds instead" ) ;
196
+ }
197
+
198
+ getSdkClient ( ) : SuiPythClient {
199
+ return new SuiPythClient (
200
+ this . getProvider ( ) ,
201
+ this . stateId ,
202
+ this . wormholeStateId
203
+ ) ;
204
+ }
205
+
206
+ async executeUpdatePriceFeedWithFeeds (
207
+ senderPrivateKey : string ,
208
+ vaas : Buffer [ ] ,
209
+ feedIds : string [ ]
210
+ ) {
211
+ const tx = new TransactionBlock ( ) ;
212
+ const client = this . getSdkClient ( ) ;
213
+ await client . updatePriceFeeds ( tx , vaas , feedIds ) ;
214
+ const keypair = Ed25519Keypair . fromSecretKey (
215
+ Buffer . from ( senderPrivateKey , "hex" )
216
+ ) ;
217
+ let result = await this . executeTransaction ( tx , keypair ) ;
218
+ return result . digest ;
219
+ }
220
+ async executeCreatePriceFeed ( senderPrivateKey : string , vaas : Buffer [ ] ) {
221
+ const tx = new TransactionBlock ( ) ;
222
+ const client = this . getSdkClient ( ) ;
223
+ await client . createPriceFeed ( tx , vaas ) ;
224
+ const keypair = Ed25519Keypair . fromSecretKey (
225
+ Buffer . from ( senderPrivateKey , "hex" )
226
+ ) ;
227
+
228
+ let result = await this . executeTransaction ( tx , keypair ) ;
229
+ return result . digest ;
200
230
}
201
231
202
232
async executeGovernanceInstruction ( senderPrivateKey : string , vaa : Buffer ) {
@@ -205,11 +235,15 @@ export class SuiContract extends Contract {
205
235
) ;
206
236
const tx = new TransactionBlock ( ) ;
207
237
const packageId = await this . getPythPackageId ( ) ;
208
- let decreeReceipt = await this . getVaaDecreeReceipt ( tx , packageId , vaa ) ;
238
+ let verificationReceipt = await this . getVaaVerificationReceipt (
239
+ tx ,
240
+ packageId ,
241
+ vaa
242
+ ) ;
209
243
210
244
tx . moveCall ( {
211
245
target : `${ packageId } ::governance::execute_governance_instruction` ,
212
- arguments : [ tx . object ( this . stateId ) , decreeReceipt ] ,
246
+ arguments : [ tx . object ( this . stateId ) , verificationReceipt ] ,
213
247
} ) ;
214
248
215
249
return this . executeTransaction ( tx , keypair ) ;
@@ -223,11 +257,15 @@ export class SuiContract extends Contract {
223
257
) {
224
258
const tx = new TransactionBlock ( ) ;
225
259
const packageId = await this . getPythPackageId ( ) ;
226
- let decreeReceipt = await this . getVaaDecreeReceipt ( tx , packageId , vaa ) ;
260
+ let verificationReceipt = await this . getVaaVerificationReceipt (
261
+ tx ,
262
+ packageId ,
263
+ vaa
264
+ ) ;
227
265
228
266
const [ upgradeTicket ] = tx . moveCall ( {
229
267
target : `${ packageId } ::contract_upgrade::authorize_upgrade` ,
230
- arguments : [ tx . object ( this . stateId ) , decreeReceipt ] ,
268
+ arguments : [ tx . object ( this . stateId ) , verificationReceipt ] ,
231
269
} ) ;
232
270
233
271
const [ upgradeReceipt ] = tx . upgrade ( {
@@ -245,23 +283,19 @@ export class SuiContract extends Contract {
245
283
}
246
284
247
285
/**
248
- * Utility function to get the decree receipt object for a VAA that can be
286
+ * Utility function to get the verification receipt object for a VAA that can be
249
287
* used to authorize a governance instruction.
250
288
* @param tx
251
289
* @param packageId pyth package id
252
290
* @param vaa
253
291
* @private
254
292
*/
255
- private async getVaaDecreeReceipt (
293
+ async getVaaVerificationReceipt (
256
294
tx : TransactionBlock ,
257
295
packageId : string ,
258
296
vaa : Buffer
259
297
) {
260
298
const wormholePackageId = await this . getWormholePackageId ( ) ;
261
- let [ decreeTicket ] = tx . moveCall ( {
262
- target : `${ packageId } ::set_update_fee::authorize_governance` ,
263
- arguments : [ tx . object ( this . stateId ) , tx . pure ( false ) ] ,
264
- } ) ;
265
299
266
300
let [ verifiedVAA ] = tx . moveCall ( {
267
301
target : `${ wormholePackageId } ::vaa::parse_and_verify` ,
@@ -272,12 +306,11 @@ export class SuiContract extends Contract {
272
306
] ,
273
307
} ) ;
274
308
275
- let [ decreeReceipt ] = tx . moveCall ( {
276
- target : `${ wormholePackageId } ::governance_message::verify_vaa` ,
277
- arguments : [ tx . object ( this . wormholeStateId ) , verifiedVAA , decreeTicket ] ,
278
- typeArguments : [ `${ packageId } ::governance_witness::GovernanceWitness` ] ,
309
+ let [ verificationReceipt ] = tx . moveCall ( {
310
+ target : `${ packageId } ::governance::verify_vaa` ,
311
+ arguments : [ tx . object ( this . stateId ) , verifiedVAA ] ,
279
312
} ) ;
280
- return decreeReceipt ;
313
+ return verificationReceipt ;
281
314
}
282
315
283
316
/**
@@ -361,7 +394,7 @@ export class SuiContract extends Contract {
361
394
return Number ( fields . last_executed_governance_sequence ) ;
362
395
}
363
396
364
- private getProvider ( ) {
397
+ getProvider ( ) {
365
398
return new JsonRpcProvider ( new Connection ( { fullnode : this . chain . rpcUrl } ) ) ;
366
399
}
367
400
0 commit comments