Fix sui js sdk and bump contract (#1071)
* Bump sui version * Add sui cli package to lerna * Fix bug in fetching price feed object ids after upgrade
This commit is contained in:
parent
916d9463b2
commit
061f6a028d
|
@ -14,6 +14,7 @@ import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
|
||||||
|
|
||||||
export class SuiContract extends Contract {
|
export class SuiContract extends Contract {
|
||||||
static type = "SuiContract";
|
static type = "SuiContract";
|
||||||
|
private client: SuiPythClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the ids of the pyth state and wormhole state, create a new SuiContract
|
* Given the ids of the pyth state and wormhole state, create a new SuiContract
|
||||||
|
@ -29,6 +30,11 @@ export class SuiContract extends Contract {
|
||||||
public wormholeStateId: string
|
public wormholeStateId: string
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this.client = new SuiPythClient(
|
||||||
|
this.getProvider(),
|
||||||
|
this.stateId,
|
||||||
|
this.wormholeStateId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(
|
static fromJson(
|
||||||
|
@ -63,8 +69,7 @@ export class SuiContract extends Contract {
|
||||||
* @param objectId
|
* @param objectId
|
||||||
*/
|
*/
|
||||||
async getPackageId(objectId: ObjectId): Promise<ObjectId> {
|
async getPackageId(objectId: ObjectId): Promise<ObjectId> {
|
||||||
const client = this.getSdkClient();
|
return this.client.getPackageId(objectId);
|
||||||
return client.getPackageId(objectId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPythPackageId(): Promise<ObjectId> {
|
async getPythPackageId(): Promise<ObjectId> {
|
||||||
|
@ -79,24 +84,6 @@ export class SuiContract extends Contract {
|
||||||
return `${this.chain.getId()}_${this.stateId}`;
|
return `${this.chain.getId()}_${this.stateId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the price table object id for the current state id
|
|
||||||
*/
|
|
||||||
async getPriceTableId(): Promise<ObjectId> {
|
|
||||||
const provider = this.getProvider();
|
|
||||||
const result = await provider.getDynamicFieldObject({
|
|
||||||
parentId: this.stateId,
|
|
||||||
name: {
|
|
||||||
type: "vector<u8>",
|
|
||||||
value: "price_info",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!result.data) {
|
|
||||||
throw new Error("Price Table not found, contract may not be initialized");
|
|
||||||
}
|
|
||||||
return result.data.objectId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async parsePrice(priceInfo: {
|
private async parsePrice(priceInfo: {
|
||||||
type: string;
|
type: string;
|
||||||
fields: {
|
fields: {
|
||||||
|
@ -125,30 +112,9 @@ export class SuiContract extends Contract {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPriceFeedObjectId(feedId: string): Promise<ObjectId | undefined> {
|
|
||||||
const tableId = await this.getPriceTableId();
|
|
||||||
const provider = this.getProvider();
|
|
||||||
const result = await provider.getDynamicFieldObject({
|
|
||||||
parentId: tableId,
|
|
||||||
name: {
|
|
||||||
type: `${await this.getPythPackageId()}::price_identifier::PriceIdentifier`,
|
|
||||||
value: {
|
|
||||||
bytes: Array.from(Buffer.from(feedId, "hex")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!result.data || !result.data.content) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (result.data.content.dataType !== "moveObject") {
|
|
||||||
throw new Error("Price feed type mismatch");
|
|
||||||
}
|
|
||||||
return result.data.content.fields.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPriceFeed(feedId: string) {
|
async getPriceFeed(feedId: string) {
|
||||||
const provider = this.getProvider();
|
const provider = this.getProvider();
|
||||||
const priceInfoObjectId = await this.getPriceFeedObjectId(feedId);
|
const priceInfoObjectId = await this.client.getPriceFeedObjectId(feedId);
|
||||||
if (!priceInfoObjectId) return undefined;
|
if (!priceInfoObjectId) return undefined;
|
||||||
const priceInfo = await provider.getObject({
|
const priceInfo = await provider.getObject({
|
||||||
id: priceInfoObjectId,
|
id: priceInfoObjectId,
|
||||||
|
@ -206,22 +172,13 @@ export class SuiContract extends Contract {
|
||||||
throw new Error("Use executeUpdatePriceFeedWithFeeds instead");
|
throw new Error("Use executeUpdatePriceFeedWithFeeds instead");
|
||||||
}
|
}
|
||||||
|
|
||||||
getSdkClient(): SuiPythClient {
|
|
||||||
return new SuiPythClient(
|
|
||||||
this.getProvider(),
|
|
||||||
this.stateId,
|
|
||||||
this.wormholeStateId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async executeUpdatePriceFeedWithFeeds(
|
async executeUpdatePriceFeedWithFeeds(
|
||||||
senderPrivateKey: string,
|
senderPrivateKey: string,
|
||||||
vaas: Buffer[],
|
vaas: Buffer[],
|
||||||
feedIds: string[]
|
feedIds: string[]
|
||||||
): Promise<TxResult> {
|
): Promise<TxResult> {
|
||||||
const tx = new TransactionBlock();
|
const tx = new TransactionBlock();
|
||||||
const client = this.getSdkClient();
|
await this.client.updatePriceFeeds(tx, vaas, feedIds);
|
||||||
await client.updatePriceFeeds(tx, vaas, feedIds);
|
|
||||||
const keypair = Ed25519Keypair.fromSecretKey(
|
const keypair = Ed25519Keypair.fromSecretKey(
|
||||||
Buffer.from(senderPrivateKey, "hex")
|
Buffer.from(senderPrivateKey, "hex")
|
||||||
);
|
);
|
||||||
|
@ -233,8 +190,7 @@ export class SuiContract extends Contract {
|
||||||
vaas: Buffer[]
|
vaas: Buffer[]
|
||||||
): Promise<TxResult> {
|
): Promise<TxResult> {
|
||||||
const tx = new TransactionBlock();
|
const tx = new TransactionBlock();
|
||||||
const client = this.getSdkClient();
|
await this.client.createPriceFeed(tx, vaas);
|
||||||
await client.createPriceFeed(tx, vaas);
|
|
||||||
const keypair = Ed25519Keypair.fromSecretKey(
|
const keypair = Ed25519Keypair.fromSecretKey(
|
||||||
Buffer.from(senderPrivateKey, "hex")
|
Buffer.from(senderPrivateKey, "hex")
|
||||||
);
|
);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,6 +17,7 @@
|
||||||
"target_chains/ethereum/sdk/solidity",
|
"target_chains/ethereum/sdk/solidity",
|
||||||
"target_chains/ethereum/examples/oracle_swap/app",
|
"target_chains/ethereum/examples/oracle_swap/app",
|
||||||
"target_chains/sui/sdk/js",
|
"target_chains/sui/sdk/js",
|
||||||
|
"target_chains/sui/cli",
|
||||||
"third_party/pyth/p2w-relay",
|
"third_party/pyth/p2w-relay",
|
||||||
"wormhole_attester/sdk/js",
|
"wormhole_attester/sdk/js",
|
||||||
"contract_manager"
|
"contract_manager"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "Pyth"
|
name = "Pyth"
|
||||||
version = "0.0.1"
|
version = "0.0.2"
|
||||||
|
|
||||||
[dependencies.Sui]
|
[dependencies.Sui]
|
||||||
git = "https://github.com/MystenLabs/sui.git"
|
git = "https://github.com/MystenLabs/sui.git"
|
||||||
|
|
|
@ -18,12 +18,12 @@ module pyth::version_control {
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public(friend) fun current_version(): V__0_1_1 {
|
public(friend) fun current_version(): V__0_1_2 {
|
||||||
V__0_1_1 {}
|
V__0_1_2 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public(friend) fun previous_version(): V__DUMMY {
|
public(friend) fun previous_version(): V__0_1_1 {
|
||||||
V__DUMMY {}
|
V__0_1_1 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -35,6 +35,11 @@ module pyth::version_control {
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// RELEASE NOTES
|
||||||
|
///
|
||||||
|
/// - Gas optimizations on merkle tree verifications
|
||||||
|
struct V__0_1_2 has store, drop, copy {}
|
||||||
|
|
||||||
/// RELEASE NOTES
|
/// RELEASE NOTES
|
||||||
///
|
///
|
||||||
/// - Refactor state to use package management via
|
/// - Refactor state to use package management via
|
||||||
|
@ -70,7 +75,7 @@ module pyth::version_control {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_only]
|
#[test_only]
|
||||||
public fun previous_version_test_only(): V__DUMMY {
|
public fun previous_version_test_only(): V__0_1_1 {
|
||||||
previous_version()
|
previous_version()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@pythnetwork/pyth-sui-js",
|
"name": "@pythnetwork/pyth-sui-js",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"description": "Pyth Network Sui Utilities",
|
"description": "Pyth Network Sui Utilities",
|
||||||
"homepage": "https://pyth.network",
|
"homepage": "https://pyth.network",
|
||||||
"author": {
|
"author": {
|
||||||
|
|
|
@ -13,7 +13,7 @@ const MAX_ARGUMENT_SIZE = 16 * 1024;
|
||||||
export class SuiPythClient {
|
export class SuiPythClient {
|
||||||
private pythPackageId: ObjectId | undefined;
|
private pythPackageId: ObjectId | undefined;
|
||||||
private wormholePackageId: ObjectId | undefined;
|
private wormholePackageId: ObjectId | undefined;
|
||||||
private priceTableId: ObjectId | undefined;
|
private priceTableInfo: { id: ObjectId; fieldType: ObjectId } | undefined;
|
||||||
private priceFeedObjectIdCache: Map<HexString, ObjectId> = new Map();
|
private priceFeedObjectIdCache: Map<HexString, ObjectId> = new Map();
|
||||||
private baseUpdateFee: number | undefined;
|
private baseUpdateFee: number | undefined;
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -260,11 +260,11 @@ export class SuiPythClient {
|
||||||
async getPriceFeedObjectId(feedId: HexString): Promise<ObjectId | undefined> {
|
async getPriceFeedObjectId(feedId: HexString): Promise<ObjectId | undefined> {
|
||||||
const normalizedFeedId = feedId.replace("0x", "");
|
const normalizedFeedId = feedId.replace("0x", "");
|
||||||
if (!this.priceFeedObjectIdCache.has(normalizedFeedId)) {
|
if (!this.priceFeedObjectIdCache.has(normalizedFeedId)) {
|
||||||
const tableId = await this.getPriceTableId();
|
const { id: tableId, fieldType } = await this.getPriceTableInfo();
|
||||||
const result = await this.provider.getDynamicFieldObject({
|
const result = await this.provider.getDynamicFieldObject({
|
||||||
parentId: tableId,
|
parentId: tableId,
|
||||||
name: {
|
name: {
|
||||||
type: `${await this.getPythPackageId()}::price_identifier::PriceIdentifier`,
|
type: `${fieldType}::price_identifier::PriceIdentifier`,
|
||||||
value: {
|
value: {
|
||||||
bytes: Array.from(Buffer.from(normalizedFeedId, "hex")),
|
bytes: Array.from(Buffer.from(normalizedFeedId, "hex")),
|
||||||
},
|
},
|
||||||
|
@ -288,8 +288,8 @@ export class SuiPythClient {
|
||||||
* Fetches the price table object id for the current state id if not cached
|
* Fetches the price table object id for the current state id if not cached
|
||||||
* @returns price table object id
|
* @returns price table object id
|
||||||
*/
|
*/
|
||||||
async getPriceTableId(): Promise<ObjectId> {
|
async getPriceTableInfo(): Promise<{ id: ObjectId; fieldType: ObjectId }> {
|
||||||
if (this.priceTableId === undefined) {
|
if (this.priceTableInfo === undefined) {
|
||||||
const result = await this.provider.getDynamicFieldObject({
|
const result = await this.provider.getDynamicFieldObject({
|
||||||
parentId: this.pythStateId,
|
parentId: this.pythStateId,
|
||||||
name: {
|
name: {
|
||||||
|
@ -297,14 +297,19 @@ export class SuiPythClient {
|
||||||
value: "price_info",
|
value: "price_info",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!result.data) {
|
if (!result.data || !result.data.type) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Price Table not found, contract may not be initialized"
|
"Price Table not found, contract may not be initialized"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.priceTableId = result.data.objectId;
|
let type = result.data.type.replace("0x2::table::Table<", "");
|
||||||
|
type = type.replace(
|
||||||
|
"::price_identifier::PriceIdentifier, 0x2::object::ID>",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
this.priceTableInfo = { id: result.data.objectId, fieldType: type };
|
||||||
}
|
}
|
||||||
return this.priceTableId;
|
return this.priceTableInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue