@pythnetwork/pyth-sui-js 1.2.5 → 2.1.0

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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2023 Pyth Contributors.
1
+ Copyright 2024 Pyth Data Association.
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -57,7 +57,8 @@ You can use `SuiPythClient` to build such transactions.
57
57
 
58
58
  ```ts
59
59
  import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
60
- import { TransactionBlock } from "@mysten/sui.js";
60
+ import { Transaction } from "@mysten/sui/transactions";
61
+ import { SuiClient } from "@mysten/sui/client";
61
62
 
62
63
  const priceUpdateData = await connection.getPriceFeedsUpdateData(priceIds); // see quickstart section
63
64
 
@@ -69,8 +70,9 @@ const wallet: SignerWithProvider = getWallet();
69
70
  const wormholeStateId = " 0xFILL_ME";
70
71
  const pythStateId = "0xFILL_ME";
71
72
 
73
+ const provider = new SuiClient({ url: "https://fill-sui-endpoint" });
72
74
  const client = new SuiPythClient(wallet.provider, pythStateId, wormholeStateId);
73
- const tx = new TransactionBlock();
75
+ const tx = new Transaction();
74
76
  const priceInfoObjectIds = await client.updatePriceFeeds(tx, priceFeedUpdateData, priceIds);
75
77
 
76
78
  tx.moveCall({
@@ -82,15 +84,14 @@ tx.moveCall({
82
84
  ],
83
85
  });
84
86
 
85
- const txBlock = {
86
- transactionBlock: tx,
87
- options: {
88
- showEffects: true,
89
- showEvents: true,
90
- },
91
- };
92
-
93
- const result = await wallet.signAndExecuteTransactionBlock(txBlock);
87
+ const result = await provider.signAndExecuteTransaction({
88
+ signer: wallet,
89
+ transaction: tx,
90
+ options: {
91
+ showEffects: true,
92
+ showEvents: true,
93
+ },
94
+ });
94
95
  ```
95
96
 
96
97
  Now in your contract you can consume the price by calling `pyth::get_price` or other utility functions on the `PriceInfoObject`.
package/lib/client.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  /// <reference types="node" />
2
- import { JsonRpcProvider, ObjectId, TransactionBlock } from "@mysten/sui.js";
2
+ import { SuiClient } from "@mysten/sui/client";
3
+ import { Transaction } from "@mysten/sui/transactions";
3
4
  import { HexString } from "@pythnetwork/price-service-client";
4
5
  import { Buffer } from "buffer";
6
+ export type ObjectId = string;
5
7
  export declare class SuiPythClient {
6
- provider: JsonRpcProvider;
8
+ provider: SuiClient;
7
9
  pythStateId: ObjectId;
8
10
  wormholeStateId: ObjectId;
9
11
  private pythPackageId;
@@ -11,7 +13,7 @@ export declare class SuiPythClient {
11
13
  private priceTableInfo;
12
14
  private priceFeedObjectIdCache;
13
15
  private baseUpdateFee;
14
- constructor(provider: JsonRpcProvider, pythStateId: ObjectId, wormholeStateId: ObjectId);
16
+ constructor(provider: SuiClient, pythStateId: ObjectId, wormholeStateId: ObjectId);
15
17
  getBaseUpdateFee(): Promise<number>;
16
18
  /**
17
19
  * getPackageId returns the latest package id that the object belongs to. Use this to
@@ -25,29 +27,18 @@ export declare class SuiPythClient {
25
27
  * @param vaas array of vaas to verify
26
28
  * @param tx transaction block to add commands to
27
29
  */
28
- verifyVaas(vaas: Buffer[], tx: TransactionBlock): Promise<({
29
- kind: "Input";
30
- index: number;
31
- type?: "object" | "pure" | undefined;
32
- value?: any;
33
- } | {
34
- kind: "GasCoin";
35
- } | {
36
- kind: "Result";
37
- index: number;
38
- } | {
39
- kind: "NestedResult";
40
- index: number;
41
- resultIndex: number;
42
- })[]>;
30
+ verifyVaas(vaas: Buffer[], tx: Transaction): Promise<{
31
+ $kind: "NestedResult";
32
+ NestedResult: [number, number];
33
+ }[]>;
43
34
  /**
44
35
  * Adds the necessary commands for updating the pyth price feeds to the transaction block.
45
36
  * @param tx transaction block to add commands to
46
37
  * @param updates array of price feed updates received from the price service
47
38
  * @param feedIds array of feed ids to update (in hex format)
48
39
  */
49
- updatePriceFeeds(tx: TransactionBlock, updates: Buffer[], feedIds: HexString[]): Promise<ObjectId[]>;
50
- createPriceFeed(tx: TransactionBlock, updates: Buffer[]): Promise<void>;
40
+ updatePriceFeeds(tx: Transaction, updates: Buffer[], feedIds: HexString[]): Promise<ObjectId[]>;
41
+ createPriceFeed(tx: Transaction, updates: Buffer[]): Promise<void>;
51
42
  /**
52
43
  * Get the packageId for the wormhole package if not already cached
53
44
  */
@@ -69,5 +60,11 @@ export declare class SuiPythClient {
69
60
  id: ObjectId;
70
61
  fieldType: ObjectId;
71
62
  }>;
63
+ /**
64
+ * Obtains the vaa bytes embedded in an accumulator message.
65
+ * @param accumulatorMessage - the accumulator price update message
66
+ * @returns vaa bytes as a uint8 array
67
+ */
68
+ extractVaaBytesFromAccumulatorMessage(accumulatorMessage: Buffer): Buffer;
72
69
  }
73
70
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";AAAA,OAAO,EAEL,eAAe,EACf,QAAQ,EAER,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,SAAS,EAGV,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,qBAAa,aAAa;IAOf,QAAQ,EAAE,eAAe;IACzB,WAAW,EAAE,QAAQ;IACrB,eAAe,EAAE,QAAQ;IARlC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,cAAc,CAAoD;IAC1E,OAAO,CAAC,sBAAsB,CAAuC;IACrE,OAAO,CAAC,aAAa,CAAqB;gBAEjC,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,QAAQ,EACrB,eAAe,EAAE,QAAQ;IAM5B,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBzC;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAuBzD;;;;OAIG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,gBAAgB;;;;;;;;;;;;;;;IAuBrD;;;;;OAKG;IACG,gBAAgB,CACpB,EAAE,EAAE,gBAAgB,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,SAAS,EAAE,GACnB,OAAO,CAAC,QAAQ,EAAE,CAAC;IA+EhB,eAAe,CAAC,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE;IA4C7D;;OAEG;IACG,oBAAoB;IAO1B;;OAEG;IACG,gBAAgB;IAOtB;;;OAGG;IACG,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IA2B5E;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,QAAQ,CAAC;QAAC,SAAS,EAAE,QAAQ,CAAA;KAAE,CAAC;CAuB1E"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,qBAAa,aAAa;IAOf,QAAQ,EAAE,SAAS;IACnB,WAAW,EAAE,QAAQ;IACrB,eAAe,EAAE,QAAQ;IARlC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,cAAc,CAAoD;IAC1E,OAAO,CAAC,sBAAsB,CAAuC;IACrE,OAAO,CAAC,aAAa,CAAqB;gBAEjC,QAAQ,EAAE,SAAS,EACnB,WAAW,EAAE,QAAQ,EACrB,eAAe,EAAE,QAAQ;IAM5B,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAoBzC;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IA0BzD;;;;OAIG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,WAAW;;;;IAwBhD;;;;;OAKG;IACG,gBAAgB,CACpB,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,SAAS,EAAE,GACnB,OAAO,CAAC,QAAQ,EAAE,CAAC;IA8DhB,eAAe,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE;IA2BxD;;OAEG;IACG,oBAAoB;IAO1B;;OAEG;IACG,gBAAgB;IAOtB;;;OAGG;IACG,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IA6B5E;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,QAAQ,CAAC;QAAC,SAAS,EAAE,QAAQ,CAAA;KAAE,CAAC;IAwBzE;;;;OAIG;IACH,qCAAqC,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM;CAY1E"}
package/lib/client.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SuiPythClient = void 0;
4
- const sui_js_1 = require("@mysten/sui.js");
5
- const price_service_client_1 = require("@pythnetwork/price-service-client");
4
+ const utils_1 = require("@mysten/sui/utils");
5
+ const bcs_1 = require("@mysten/sui/bcs");
6
6
  const buffer_1 = require("buffer");
7
7
  const MAX_ARGUMENT_SIZE = 16 * 1024;
8
8
  class SuiPythClient {
@@ -31,6 +31,8 @@ class SuiPythClient {
31
31
  !result.data.content ||
32
32
  result.data.content.dataType !== "moveObject")
33
33
  throw new Error("Unable to fetch pyth state object");
34
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
35
+ // @ts-ignore
34
36
  this.baseUpdateFee = result.data.content.fields.base_update_fee;
35
37
  }
36
38
  return this.baseUpdateFee;
@@ -53,9 +55,12 @@ class SuiPythClient {
53
55
  if (result.data?.content?.dataType == "moveObject") {
54
56
  return result.data.content.fields;
55
57
  }
56
- throw new Error("not move object");
58
+ console.log(result.data?.content);
59
+ throw new Error(`Cannot fetch package id for object ${objectId}`);
57
60
  });
58
61
  if ("upgrade_cap" in state) {
62
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
63
+ // @ts-ignore
59
64
  return state.upgrade_cap.fields.package;
60
65
  }
61
66
  throw new Error("upgrade_cap not found");
@@ -73,12 +78,13 @@ class SuiPythClient {
73
78
  target: `${wormholePackageId}::vaa::parse_and_verify`,
74
79
  arguments: [
75
80
  tx.object(this.wormholeStateId),
76
- tx.pure(sui_js_1.builder
77
- .ser("vector<u8>", Array.from(vaa), {
81
+ tx.pure(bcs_1.bcs
82
+ .vector(bcs_1.bcs.U8)
83
+ .serialize(Array.from(vaa), {
78
84
  maxSize: MAX_ARGUMENT_SIZE,
79
85
  })
80
86
  .toBytes()),
81
- tx.object(sui_js_1.SUI_CLOCK_OBJECT_ID),
87
+ tx.object(utils_1.SUI_CLOCK_OBJECT_ID),
82
88
  ],
83
89
  });
84
90
  verifiedVaas.push(verifiedVaa);
@@ -92,49 +98,30 @@ class SuiPythClient {
92
98
  * @param feedIds array of feed ids to update (in hex format)
93
99
  */
94
100
  async updatePriceFeeds(tx, updates, feedIds) {
95
- const wormholePackageId = await this.getWormholePackageId();
96
101
  const packageId = await this.getPythPackageId();
97
102
  let priceUpdatesHotPotato;
98
- if (updates.every((update) => (0, price_service_client_1.isAccumulatorUpdateData)(update))) {
99
- if (updates.length > 1) {
100
- throw new Error("SDK does not support sending multiple accumulator messages in a single transaction");
101
- }
102
- const vaa = (0, price_service_client_1.parseAccumulatorUpdateData)(updates[0]).vaa;
103
- const verifiedVaas = await this.verifyVaas([vaa], tx);
104
- [priceUpdatesHotPotato] = tx.moveCall({
105
- target: `${packageId}::pyth::create_authenticated_price_infos_using_accumulator`,
106
- arguments: [
107
- tx.object(this.pythStateId),
108
- tx.pure(sui_js_1.builder
109
- .ser("vector<u8>", Array.from(updates[0]), {
110
- maxSize: MAX_ARGUMENT_SIZE,
111
- })
112
- .toBytes()),
113
- verifiedVaas[0],
114
- tx.object(sui_js_1.SUI_CLOCK_OBJECT_ID),
115
- ],
116
- });
117
- }
118
- else if (updates.every((vaa) => !(0, price_service_client_1.isAccumulatorUpdateData)(vaa))) {
119
- const verifiedVaas = await this.verifyVaas(updates, tx);
120
- [priceUpdatesHotPotato] = tx.moveCall({
121
- target: `${packageId}::pyth::create_price_infos_hot_potato`,
122
- arguments: [
123
- tx.object(this.pythStateId),
124
- tx.makeMoveVec({
125
- type: `${wormholePackageId}::vaa::VAA`,
126
- objects: verifiedVaas,
127
- }),
128
- tx.object(sui_js_1.SUI_CLOCK_OBJECT_ID),
129
- ],
130
- });
131
- }
132
- else {
133
- throw new Error("Can't mix accumulator and non-accumulator messages");
103
+ if (updates.length > 1) {
104
+ throw new Error("SDK does not support sending multiple accumulator messages in a single transaction");
134
105
  }
106
+ const vaa = this.extractVaaBytesFromAccumulatorMessage(updates[0]);
107
+ const verifiedVaas = await this.verifyVaas([vaa], tx);
108
+ [priceUpdatesHotPotato] = tx.moveCall({
109
+ target: `${packageId}::pyth::create_authenticated_price_infos_using_accumulator`,
110
+ arguments: [
111
+ tx.object(this.pythStateId),
112
+ tx.pure(bcs_1.bcs
113
+ .vector(bcs_1.bcs.U8)
114
+ .serialize(Array.from(updates[0]), {
115
+ maxSize: MAX_ARGUMENT_SIZE,
116
+ })
117
+ .toBytes()),
118
+ verifiedVaas[0],
119
+ tx.object(utils_1.SUI_CLOCK_OBJECT_ID),
120
+ ],
121
+ });
135
122
  const priceInfoObjects = [];
136
123
  const baseUpdateFee = await this.getBaseUpdateFee();
137
- const coins = tx.splitCoins(tx.gas, feedIds.map(() => tx.pure(baseUpdateFee)));
124
+ const coins = tx.splitCoins(tx.gas, feedIds.map(() => tx.pure.u64(baseUpdateFee)));
138
125
  let coinId = 0;
139
126
  for (const feedId of feedIds) {
140
127
  const priceInfoObjectId = await this.getPriceFeedObjectId(feedId);
@@ -149,7 +136,7 @@ class SuiPythClient {
149
136
  priceUpdatesHotPotato,
150
137
  tx.object(priceInfoObjectId),
151
138
  coins[coinId],
152
- tx.object(sui_js_1.SUI_CLOCK_OBJECT_ID),
139
+ tx.object(utils_1.SUI_CLOCK_OBJECT_ID),
153
140
  ],
154
141
  });
155
142
  coinId++;
@@ -162,45 +149,26 @@ class SuiPythClient {
162
149
  return priceInfoObjects;
163
150
  }
164
151
  async createPriceFeed(tx, updates) {
165
- const wormholePackageId = await this.getWormholePackageId();
166
152
  const packageId = await this.getPythPackageId();
167
- if (updates.every((update) => (0, price_service_client_1.isAccumulatorUpdateData)(update))) {
168
- if (updates.length > 1) {
169
- throw new Error("SDK does not support sending multiple accumulator messages in a single transaction");
170
- }
171
- const vaa = (0, price_service_client_1.parseAccumulatorUpdateData)(updates[0]).vaa;
172
- const verifiedVaas = await this.verifyVaas([vaa], tx);
173
- tx.moveCall({
174
- target: `${packageId}::pyth::create_price_feeds_using_accumulator`,
175
- arguments: [
176
- tx.object(this.pythStateId),
177
- tx.pure(sui_js_1.builder
178
- .ser("vector<u8>", Array.from(updates[0]), {
179
- maxSize: MAX_ARGUMENT_SIZE,
180
- })
181
- .toBytes()),
182
- verifiedVaas[0],
183
- tx.object(sui_js_1.SUI_CLOCK_OBJECT_ID),
184
- ],
185
- });
186
- }
187
- else if (updates.every((vaa) => !(0, price_service_client_1.isAccumulatorUpdateData)(vaa))) {
188
- const verifiedVaas = await this.verifyVaas(updates, tx);
189
- tx.moveCall({
190
- target: `${packageId}::pyth::create_price_feeds`,
191
- arguments: [
192
- tx.object(this.pythStateId),
193
- tx.makeMoveVec({
194
- type: `${wormholePackageId}::vaa::VAA`,
195
- objects: verifiedVaas,
196
- }),
197
- tx.object(sui_js_1.SUI_CLOCK_OBJECT_ID),
198
- ],
199
- });
200
- }
201
- else {
202
- throw new Error("Can't mix accumulator and non-accumulator messages");
153
+ if (updates.length > 1) {
154
+ throw new Error("SDK does not support sending multiple accumulator messages in a single transaction");
203
155
  }
156
+ const vaa = this.extractVaaBytesFromAccumulatorMessage(updates[0]);
157
+ const verifiedVaas = await this.verifyVaas([vaa], tx);
158
+ tx.moveCall({
159
+ target: `${packageId}::pyth::create_price_feeds_using_accumulator`,
160
+ arguments: [
161
+ tx.object(this.pythStateId),
162
+ tx.pure(bcs_1.bcs
163
+ .vector(bcs_1.bcs.U8)
164
+ .serialize(Array.from(updates[0]), {
165
+ maxSize: MAX_ARGUMENT_SIZE,
166
+ })
167
+ .toBytes()),
168
+ verifiedVaas[0],
169
+ tx.object(utils_1.SUI_CLOCK_OBJECT_ID),
170
+ ],
171
+ });
204
172
  }
205
173
  /**
206
174
  * Get the packageId for the wormhole package if not already cached
@@ -243,7 +211,10 @@ class SuiPythClient {
243
211
  if (result.data.content.dataType !== "moveObject") {
244
212
  throw new Error("Price feed type mismatch");
245
213
  }
246
- this.priceFeedObjectIdCache.set(normalizedFeedId, result.data.content.fields.value);
214
+ this.priceFeedObjectIdCache.set(normalizedFeedId,
215
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
216
+ // @ts-ignore
217
+ result.data.content.fields.value);
247
218
  }
248
219
  return this.priceFeedObjectIdCache.get(normalizedFeedId);
249
220
  }
@@ -269,5 +240,21 @@ class SuiPythClient {
269
240
  }
270
241
  return this.priceTableInfo;
271
242
  }
243
+ /**
244
+ * Obtains the vaa bytes embedded in an accumulator message.
245
+ * @param accumulatorMessage - the accumulator price update message
246
+ * @returns vaa bytes as a uint8 array
247
+ */
248
+ extractVaaBytesFromAccumulatorMessage(accumulatorMessage) {
249
+ // the first 6 bytes in the accumulator message encode the header, major, and minor bytes
250
+ // we ignore them, since we are only interested in the VAA bytes
251
+ const trailingPayloadSize = accumulatorMessage.readUint8(6);
252
+ const vaaSizeOffset = 7 + // header bytes (header(4) + major(1) + minor(1) + trailing payload size(1))
253
+ trailingPayloadSize + // trailing payload (variable number of bytes)
254
+ 1; // proof_type (1 byte)
255
+ const vaaSize = accumulatorMessage.readUint16BE(vaaSizeOffset);
256
+ const vaaOffset = vaaSizeOffset + 2;
257
+ return accumulatorMessage.subarray(vaaOffset, vaaOffset + vaaSize);
258
+ }
272
259
  }
273
260
  exports.SuiPythClient = SuiPythClient;
@@ -1,3 +1,3 @@
1
- import { JsonRpcProvider } from "@mysten/sui.js";
2
- export declare function getProvider(url: string): JsonRpcProvider;
1
+ import { SuiClient } from "@mysten/sui/client";
2
+ export declare function getProvider(url: string): SuiClient;
3
3
  //# sourceMappingURL=SuiRelay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SuiRelay.d.ts","sourceRoot":"","sources":["../../src/examples/SuiRelay.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,eAAe,EAGhB,MAAM,gBAAgB,CAAC;AAkCxB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,mBAEtC"}
1
+ {"version":3,"file":"SuiRelay.d.ts","sourceRoot":"","sources":["../../src/examples/SuiRelay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAqC/C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,aAEtC"}
@@ -6,9 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getProvider = void 0;
7
7
  const yargs_1 = __importDefault(require("yargs"));
8
8
  const helpers_1 = require("yargs/helpers");
9
- const sui_js_1 = require("@mysten/sui.js");
9
+ const client_1 = require("@mysten/sui/client");
10
+ const transactions_1 = require("@mysten/sui/transactions");
11
+ const ed25519_1 = require("@mysten/sui/keypairs/ed25519");
10
12
  const buffer_1 = require("buffer");
11
- const client_1 = require("../client");
13
+ const client_2 = require("../client");
12
14
  const index_1 = require("../index");
13
15
  const argvPromise = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
14
16
  .option("feed-id", {
@@ -37,7 +39,7 @@ const argvPromise = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
37
39
  demandOption: true,
38
40
  }).argv;
39
41
  function getProvider(url) {
40
- return new sui_js_1.JsonRpcProvider(new sui_js_1.Connection({ fullnode: url }));
42
+ return new client_1.SuiClient({ url });
41
43
  }
42
44
  exports.getProvider = getProvider;
43
45
  async function run() {
@@ -48,22 +50,42 @@ async function run() {
48
50
  // Fetch the latest price feed update data from the Price Service
49
51
  const connection = new index_1.SuiPriceServiceConnection(argv["hermes"]);
50
52
  const feeds = argv["feed-id"];
51
- const priceFeedUpdateData = await connection.getPriceFeedsUpdateData(feeds);
52
53
  const provider = getProvider(argv["full-node"]);
53
54
  const wormholeStateId = argv["wormhole-state-id"];
54
55
  const pythStateId = argv["pyth-state-id"];
55
- const client = new client_1.SuiPythClient(provider, pythStateId, wormholeStateId);
56
- const tx = new sui_js_1.TransactionBlock();
57
- await client.updatePriceFeeds(tx, priceFeedUpdateData, feeds);
58
- const wallet = new sui_js_1.RawSigner(sui_js_1.Ed25519Keypair.fromSecretKey(buffer_1.Buffer.from(process.env.SUI_KEY, "hex")), provider);
59
- const txBlock = {
60
- transactionBlock: tx,
56
+ const client = new client_2.SuiPythClient(provider, pythStateId, wormholeStateId);
57
+ const newFeeds = [];
58
+ const existingFeeds = [];
59
+ for (const feed of feeds) {
60
+ if ((await client.getPriceFeedObjectId(feed)) == undefined) {
61
+ newFeeds.push(feed);
62
+ }
63
+ else {
64
+ existingFeeds.push(feed);
65
+ }
66
+ }
67
+ console.log({
68
+ newFeeds,
69
+ existingFeeds,
70
+ });
71
+ const tx = new transactions_1.Transaction();
72
+ if (existingFeeds.length > 0) {
73
+ const updateData = await connection.getPriceFeedsUpdateData(existingFeeds);
74
+ await client.updatePriceFeeds(tx, updateData, existingFeeds);
75
+ }
76
+ if (newFeeds.length > 0) {
77
+ const updateData = await connection.getPriceFeedsUpdateData(newFeeds);
78
+ await client.createPriceFeed(tx, updateData);
79
+ }
80
+ const wallet = ed25519_1.Ed25519Keypair.fromSecretKey(buffer_1.Buffer.from(process.env.SUI_KEY, "hex"));
81
+ const result = await provider.signAndExecuteTransaction({
82
+ signer: wallet,
83
+ transaction: tx,
61
84
  options: {
62
85
  showEffects: true,
63
86
  showEvents: true,
64
87
  },
65
- };
66
- const result = await wallet.signAndExecuteTransactionBlock(txBlock);
88
+ });
67
89
  console.dir(result, { depth: null });
68
90
  }
69
91
  run();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pythnetwork/pyth-sui-js",
3
- "version": "1.2.5",
3
+ "version": "2.1.0",
4
4
  "description": "Pyth Network Sui Utilities",
5
5
  "homepage": "https://pyth.network",
6
6
  "author": {
@@ -22,12 +22,12 @@
22
22
  "scripts": {
23
23
  "test": "jest --passWithNoTests",
24
24
  "build": "tsc",
25
- "example-relay": "npm run build && node lib/examples/SuiRelay.js",
25
+ "example-relay": "pnpm run build && node lib/examples/SuiRelay.js",
26
26
  "format": "prettier --write \"src/**/*.ts\"",
27
27
  "lint": "eslint src/",
28
- "prepublishOnly": "npm run build && npm test && npm run lint",
29
- "preversion": "npm run lint",
30
- "version": "npm run format && git add -A src"
28
+ "prepublishOnly": "pnpm run build && pnpm test && pnpm run lint",
29
+ "preversion": "pnpm run lint",
30
+ "version": "pnpm run format && git add -A src"
31
31
  },
32
32
  "keywords": [
33
33
  "pyth",
@@ -42,20 +42,20 @@
42
42
  "@types/node": "^18.11.18",
43
43
  "@types/web3-provider-engine": "^14.0.1",
44
44
  "@types/yargs": "^17.0.20",
45
- "@typescript-eslint/eslint-plugin": "^5.21.0",
46
- "@typescript-eslint/parser": "^5.21.0",
45
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
46
+ "@typescript-eslint/parser": "^6.0.0",
47
47
  "eslint": "^8.14.0",
48
48
  "jest": "^29.4.1",
49
49
  "prettier": "^2.6.2",
50
50
  "ts-jest": "^29.0.5",
51
- "typescript": "^4.6.3",
51
+ "typescript": "^5.3.3",
52
52
  "web3": "^1.8.2",
53
53
  "yargs": "^17.0.20"
54
54
  },
55
55
  "dependencies": {
56
- "@mysten/sui.js": "^0.37.1",
57
- "@pythnetwork/price-service-client": "*",
56
+ "@mysten/sui": "^1.3.0",
57
+ "@pythnetwork/price-service-client": "1.9.0",
58
58
  "buffer": "^6.0.3"
59
59
  },
60
- "gitHead": "0d49986eb1cd77c969059bcb72857e90ba8ae4f8"
60
+ "gitHead": "9a31948be215682091abe580a68666909b976462"
61
61
  }