@pythnetwork/price-pusher 6.1.0 → 6.3.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 CHANGED
@@ -133,6 +133,18 @@ npm run start -- sui \
133
133
  [--polling-frequency 5] \
134
134
  [--num-gas-objects 30]
135
135
 
136
+ # For Near
137
+ npm run start -- near \
138
+ --node-url https://rpc.testnet.near.org \
139
+ --network testnet \
140
+ --account-id payer.testnet \
141
+ --pyth-contract-address pyth-oracle.testnet \
142
+ --price-service-endpoint "https://hermes-beta.pyth.network" \
143
+ --price-config-file ./price-config.beta.sample.yaml \
144
+ [--private-key-path ./payer.testnet.json] \
145
+ [--pushing-frequency 10] \
146
+ [--polling-frequency 5]
147
+
136
148
 
137
149
  # Or, run the price pusher docker image instead of building from the source
138
150
  docker run public.ecr.aws/pyth-network/xc-price-pusher:v<version> -- <above-arguments>
@@ -195,9 +207,9 @@ It will take a few minutes until all the services are up and running.
195
207
  ## Reliability
196
208
 
197
209
  You can run multiple instances of the price pusher to increase the reliability. It is better to use
198
- difference RPCs to get better reliability in case an RPC goes down. **If you use the same payer account
210
+ different RPCs to get better reliability in case an RPC goes down. **If you use the same payer account
199
211
  in different pushers, then due to blockchains nonce or sequence for accounts, a transaction won't be
200
- pushed twiced and you won't pay additional costs most of the time.** However, there might be some race
201
- condiitons in the RPCs because they are often behind a load balancer than can sometimes cause rejected
202
- transactions land on-chain. You can reduce the chances of additional cost overhead by reducing the
212
+ pushed twice and you won't pay additional costs most of the time.** However, there might be some race
213
+ conditions in the RPCs because they are often behind a load balancer which can sometimes cause rejected
214
+ transactions to land on-chain. You can reduce the chances of additional cost overhead by reducing the
203
215
  pushing frequency.
@@ -1 +1 @@
1
- {"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/evm/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAgB,iBAAiB,EAAmB,MAAM,UAAU,CAAC;AAE5E,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAG1D,OAAO,EACL,sBAAsB,EACtB,SAAS,EACT,aAAa,EACd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAIxD,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,YAAY,CAAW;gBAG7B,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,KAAK;YAeG,iBAAiB;IAc/B,OAAO,CAAC,iBAAiB;IAsBnB,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAwBlC;AAED,qBAAa,cAAe,YAAW,YAAY;IAQ/C,OAAO,CAAC,UAAU;IAElB,OAAO,CAAC,0BAA0B;IAClC,OAAO,CAAC,6BAA6B;IAVvC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,eAAe,CAA0B;gBAGvC,UAAU,EAAE,sBAAsB,EAC1C,mBAAmB,EAAE,mBAAmB,EAChC,0BAA0B,EAAE,MAAM,EAClC,6BAA6B,EAAE,MAAM,EAC7C,gBAAgB,CAAC,EAAE,gBAAgB;IAa/B,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;YAgJF,uBAAuB;CAQtC;AAED,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,mBAAmB;gBAFnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM;IAGrC;;;;;;OAMG;IACH,2BAA2B,IAAI,QAAQ;IAcvC;;;;;OAKG;IACH,kBAAkB,IAAI,QAAQ;IAS9B,oBAAoB,IAAI,OAAO;IAI/B,kBAAkB;IA0BlB,uBAAuB;CAQxB"}
1
+ {"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/evm/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAgB,iBAAiB,EAAmB,MAAM,UAAU,CAAC;AAE5E,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAG1D,OAAO,EACL,sBAAsB,EACtB,SAAS,EACT,aAAa,EACd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAIxD,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,YAAY,CAAW;gBAG7B,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,KAAK;YAeG,iBAAiB;IAc/B,OAAO,CAAC,iBAAiB;IAsBnB,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAwBlC;AAED,qBAAa,cAAe,YAAW,YAAY;IAQ/C,OAAO,CAAC,UAAU;IAElB,OAAO,CAAC,0BAA0B;IAClC,OAAO,CAAC,6BAA6B;IAVvC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,eAAe,CAA0B;gBAGvC,UAAU,EAAE,sBAAsB,EAC1C,mBAAmB,EAAE,mBAAmB,EAChC,0BAA0B,EAAE,MAAM,EAClC,6BAA6B,EAAE,MAAM,EAC7C,gBAAgB,CAAC,EAAE,gBAAgB;IAa/B,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;YAiJF,uBAAuB;CAQtC;AAED,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,mBAAmB;gBAFnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM;IAGrC;;;;;;OAMG;IACH,2BAA2B,IAAI,QAAQ;IAcvC;;;;;OAKG;IACH,kBAAkB,IAAI,QAAQ;IAS9B,oBAAoB,IAAI,OAAO;IAI/B,kBAAkB;IA0BlB,uBAAuB;CAQxB"}
package/lib/evm/evm.js CHANGED
@@ -158,8 +158,9 @@ class EvmPricePusher {
158
158
  return;
159
159
  }
160
160
  if (err.message.includes("the tx doesn't have the correct nonce.") ||
161
- err.message.includes("nonce too low")) {
162
- console.log("Multiple users are using the same accounts and nonce is incorrect. Skipping this push.");
161
+ err.message.includes("nonce too low") ||
162
+ err.message.includes("invalid nonce")) {
163
+ console.log("The nonce is incorrect (are multiple users using this account?). Skipping this push.");
163
164
  return;
164
165
  }
165
166
  if (err.message.includes("max fee per gas less than block base fee")) {
package/lib/index.js CHANGED
@@ -10,6 +10,7 @@ const command_1 = __importDefault(require("./injective/command"));
10
10
  const command_2 = __importDefault(require("./evm/command"));
11
11
  const command_3 = __importDefault(require("./aptos/command"));
12
12
  const command_4 = __importDefault(require("./sui/command"));
13
+ const command_5 = __importDefault(require("./near/command"));
13
14
  (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
14
15
  .config("config")
15
16
  .global("config")
@@ -17,4 +18,5 @@ const command_4 = __importDefault(require("./sui/command"));
17
18
  .command(command_1.default)
18
19
  .command(command_3.default)
19
20
  .command(command_4.default)
21
+ .command(command_5.default)
20
22
  .help().argv;
@@ -0,0 +1,19 @@
1
+ import { Options } from "yargs";
2
+ declare const _default: {
3
+ command: string;
4
+ describe: string;
5
+ builder: {
6
+ "pushing-frequency": Options;
7
+ "polling-frequency": Options;
8
+ "pyth-contract-address": Options;
9
+ "price-service-endpoint": Options;
10
+ "price-config-file": Options;
11
+ "node-url": Options;
12
+ network: Options;
13
+ "account-id": Options;
14
+ "private-key-path": Options;
15
+ };
16
+ handler: (argv: any) => void;
17
+ };
18
+ export default _default;
19
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/near/command.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;oBAkCL,GAAG;;AA/B9B,wBA2FE"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const price_service_client_1 = require("@pythnetwork/price-service-client");
27
+ const options = __importStar(require("../options"));
28
+ const price_config_1 = require("../price-config");
29
+ const pyth_price_listener_1 = require("../pyth-price-listener");
30
+ const controller_1 = require("../controller");
31
+ const near_1 = require("./near");
32
+ exports.default = {
33
+ command: "near",
34
+ describe: "run price pusher for near",
35
+ builder: {
36
+ "node-url": {
37
+ description: "NEAR RPC API url. used to make JSON RPC calls to interact with NEAR.",
38
+ type: "string",
39
+ required: true,
40
+ },
41
+ network: {
42
+ description: "testnet or mainnet.",
43
+ type: "string",
44
+ required: true,
45
+ },
46
+ "account-id": {
47
+ description: "payer account identifier.",
48
+ type: "string",
49
+ required: true,
50
+ },
51
+ "private-key-path": {
52
+ description: "path to payer private key file.",
53
+ type: "string",
54
+ required: false,
55
+ },
56
+ ...options.priceConfigFile,
57
+ ...options.priceServiceEndpoint,
58
+ ...options.pythContractAddress,
59
+ ...options.pollingFrequency,
60
+ ...options.pushingFrequency,
61
+ },
62
+ handler: function (argv) {
63
+ // FIXME: type checks for this
64
+ const { nodeUrl, network, accountId, privateKeyPath, priceConfigFile, priceServiceEndpoint, pythContractAddress, pushingFrequency, pollingFrequency, } = argv;
65
+ const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
66
+ const priceServiceConnection = new price_service_client_1.PriceServiceConnection(priceServiceEndpoint, {
67
+ logger: {
68
+ // Log only warnings and errors from the price service client
69
+ info: () => undefined,
70
+ warn: console.warn,
71
+ error: console.error,
72
+ debug: () => undefined,
73
+ trace: () => undefined,
74
+ },
75
+ });
76
+ const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
77
+ const pythListener = new pyth_price_listener_1.PythPriceListener(priceServiceConnection, priceItems);
78
+ const nearAccount = new near_1.NearAccount(network, accountId, nodeUrl, privateKeyPath, pythContractAddress);
79
+ const nearListener = new near_1.NearPriceListener(nearAccount, priceItems, {
80
+ pollingFrequency,
81
+ });
82
+ const nearPusher = new near_1.NearPricePusher(nearAccount, priceServiceConnection);
83
+ const controller = new controller_1.Controller(priceConfigs, pythListener, nearListener, nearPusher, { pushingFrequency });
84
+ controller.start();
85
+ },
86
+ };
@@ -0,0 +1,28 @@
1
+ import { IPricePusher, PriceInfo, ChainPriceListener, PriceItem } from "../interface";
2
+ import { PriceServiceConnection } from "@pythnetwork/price-service-client";
3
+ import { DurationInSeconds } from "../utils";
4
+ import { FinalExecutionOutcome } from "near-api-js/lib/providers/provider";
5
+ export declare class NearPriceListener extends ChainPriceListener {
6
+ private account;
7
+ constructor(account: NearAccount, priceItems: PriceItem[], config: {
8
+ pollingFrequency: DurationInSeconds;
9
+ });
10
+ getOnChainPriceInfo(priceId: string): Promise<PriceInfo | undefined>;
11
+ }
12
+ export declare class NearPricePusher implements IPricePusher {
13
+ private account;
14
+ private connection;
15
+ constructor(account: NearAccount, connection: PriceServiceConnection);
16
+ updatePriceFeed(priceIds: string[], pubTimesToPush: number[]): Promise<void>;
17
+ private getPriceFeedsUpdateData;
18
+ }
19
+ export declare class NearAccount {
20
+ private pythAccountId;
21
+ private account;
22
+ constructor(network: string, accountId: string, nodeUrl: string, privateKeyPath: string | undefined, pythAccountId: string);
23
+ getPriceUnsafe(priceId: string): Promise<any>;
24
+ getUpdateFeeEstimate(data: string): Promise<any>;
25
+ updatePriceFeeds(data: string, updateFee: any): Promise<FinalExecutionOutcome>;
26
+ private getConnection;
27
+ }
28
+ //# sourceMappingURL=near.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"near.d.ts","sourceRoot":"","sources":["../../src/near/near.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,sBAAsB,EAEvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EAGL,qBAAqB,EACtB,MAAM,oCAAoC,CAAC;AAG5C,qBAAa,iBAAkB,SAAQ,kBAAkB;IAErD,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW,EAC5B,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAyB3E;AAED,qBAAa,eAAgB,YAAW,YAAY;IAEhD,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;gBADV,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,sBAAsB;IAGtC,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;YAiEF,uBAAuB;CAMtC;AAED,qBAAa,WAAW;IAQpB,OAAO,CAAC,aAAa;IAPvB,OAAO,CAAC,OAAO,CAAU;gBAGvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,GAAG,SAAS,EAC1B,aAAa,EAAE,MAAM;IAWzB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAU7C,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAUhD,gBAAgB,CACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,GAAG,GACb,OAAO,CAAC,qBAAqB,CAAC;IAYjC,OAAO,CAAC,aAAa;CAkCtB"}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NearAccount = exports.NearPricePusher = exports.NearPriceListener = void 0;
7
+ const os_1 = __importDefault(require("os"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const interface_1 = require("../interface");
11
+ const near_api_js_1 = require("near-api-js");
12
+ const key_stores_1 = require("near-api-js/lib/key_stores");
13
+ class NearPriceListener extends interface_1.ChainPriceListener {
14
+ account;
15
+ constructor(account, priceItems, config) {
16
+ super("near", config.pollingFrequency, priceItems);
17
+ this.account = account;
18
+ }
19
+ async getOnChainPriceInfo(priceId) {
20
+ try {
21
+ const priceRaw = await this.account.getPriceUnsafe(priceId);
22
+ console.log(`Polled a NEAR on chain price for feed ${this.priceIdToAlias.get(priceId)} (${priceId}) ${JSON.stringify(priceRaw)}.`);
23
+ if (priceRaw) {
24
+ return {
25
+ conf: priceRaw.conf,
26
+ price: priceRaw.price,
27
+ publishTime: priceRaw.publish_time,
28
+ };
29
+ }
30
+ else {
31
+ return undefined;
32
+ }
33
+ }
34
+ catch (e) {
35
+ console.error(`Polling on-chain price for ${priceId} failed. Error:`);
36
+ console.error(e);
37
+ return undefined;
38
+ }
39
+ }
40
+ }
41
+ exports.NearPriceListener = NearPriceListener;
42
+ class NearPricePusher {
43
+ account;
44
+ connection;
45
+ constructor(account, connection) {
46
+ this.account = account;
47
+ this.connection = connection;
48
+ }
49
+ async updatePriceFeed(priceIds, pubTimesToPush) {
50
+ if (priceIds.length === 0) {
51
+ return;
52
+ }
53
+ if (priceIds.length !== pubTimesToPush.length)
54
+ throw new Error("Invalid arguments");
55
+ let priceFeedUpdateData;
56
+ try {
57
+ priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds);
58
+ }
59
+ catch (e) {
60
+ console.error(new Date(), "getPriceFeedsUpdateData failed:", e);
61
+ return;
62
+ }
63
+ console.log("Pushing ", priceIds);
64
+ for (const data of priceFeedUpdateData) {
65
+ let updateFee;
66
+ try {
67
+ updateFee = await this.account.getUpdateFeeEstimate(data);
68
+ console.log(`Update fee: ${updateFee}`);
69
+ }
70
+ catch (e) {
71
+ console.error(new Date(), "getUpdateFeeEstimate failed:", e);
72
+ continue;
73
+ }
74
+ try {
75
+ const outcome = await this.account.updatePriceFeeds(data, updateFee);
76
+ const failureMessages = [];
77
+ const is_success = Object.values(outcome["receipts_outcome"]).reduce((is_success, receipt) => {
78
+ if (Object.prototype.hasOwnProperty.call(receipt["outcome"]["status"], "Failure")) {
79
+ failureMessages.push(receipt["outcome"]["status"]);
80
+ return false;
81
+ }
82
+ return is_success;
83
+ }, true);
84
+ if (is_success) {
85
+ console.log(new Date(), "updatePriceFeeds successful. Tx hash: ", outcome["transaction"]["hash"]);
86
+ }
87
+ else {
88
+ console.error(new Date(), "updatePriceFeeds failed:", JSON.stringify(failureMessages, undefined, 2));
89
+ }
90
+ }
91
+ catch (e) {
92
+ console.error(new Date(), "updatePriceFeeds failed:", e);
93
+ }
94
+ }
95
+ }
96
+ async getPriceFeedsUpdateData(priceIds) {
97
+ const latestVaas = await this.connection.getLatestVaas(priceIds);
98
+ return latestVaas.map((vaa) => Buffer.from(vaa, "base64").toString("hex"));
99
+ }
100
+ }
101
+ exports.NearPricePusher = NearPricePusher;
102
+ class NearAccount {
103
+ pythAccountId;
104
+ account;
105
+ constructor(network, accountId, nodeUrl, privateKeyPath, pythAccountId) {
106
+ this.pythAccountId = pythAccountId;
107
+ const connection = this.getConnection(network, accountId, nodeUrl, privateKeyPath);
108
+ this.account = new near_api_js_1.Account(connection, accountId);
109
+ }
110
+ async getPriceUnsafe(priceId) {
111
+ return await this.account.viewFunction({
112
+ contractId: this.pythAccountId,
113
+ methodName: "get_price_unsafe",
114
+ args: {
115
+ price_identifier: priceId,
116
+ },
117
+ });
118
+ }
119
+ async getUpdateFeeEstimate(data) {
120
+ return await this.account.viewFunction({
121
+ contractId: this.pythAccountId,
122
+ methodName: "get_update_fee_estimate",
123
+ args: {
124
+ data,
125
+ },
126
+ });
127
+ }
128
+ async updatePriceFeeds(data, updateFee) {
129
+ return await this.account.functionCall({
130
+ contractId: this.pythAccountId,
131
+ methodName: "update_price_feeds",
132
+ args: {
133
+ data,
134
+ },
135
+ gas: "300000000000000",
136
+ attachedDeposit: updateFee,
137
+ });
138
+ }
139
+ getConnection(network, accountId, nodeUrl, privateKeyPath) {
140
+ const content = fs_1.default.readFileSync(privateKeyPath ||
141
+ path_1.default.join(os_1.default.homedir(), ".near-credentials", network, accountId + ".json"));
142
+ const accountInfo = JSON.parse(content.toString());
143
+ let privateKey = accountInfo.private_key;
144
+ if (!privateKey && accountInfo.secret_key) {
145
+ privateKey = accountInfo.secret_key;
146
+ }
147
+ if (accountInfo.account_id && privateKey) {
148
+ const keyPair = near_api_js_1.KeyPair.fromString(privateKey);
149
+ const keyStore = new key_stores_1.InMemoryKeyStore();
150
+ keyStore.setKey(network, accountInfo.account_id, keyPair);
151
+ return near_api_js_1.Connection.fromConfig({
152
+ networkId: network,
153
+ provider: { type: "JsonRpcProvider", args: { url: nodeUrl } },
154
+ signer: { type: "InMemorySigner", keyStore },
155
+ jsvmAccountId: `jsvm.${network}`,
156
+ });
157
+ }
158
+ else {
159
+ throw new Error("Invalid key file!");
160
+ }
161
+ }
162
+ }
163
+ exports.NearAccount = NearAccount;
@@ -56,7 +56,7 @@ var UpdateCondition;
56
56
  UpdateCondition[UpdateCondition["EARLY"] = 1] = "EARLY";
57
57
  // This price feed shouldn't be updated
58
58
  UpdateCondition[UpdateCondition["NO"] = 2] = "NO";
59
- })(UpdateCondition = exports.UpdateCondition || (exports.UpdateCondition = {}));
59
+ })(UpdateCondition || (exports.UpdateCondition = UpdateCondition = {}));
60
60
  /**
61
61
  * Checks whether on-chain price needs to be updated with the latest pyth price information.
62
62
  *
@@ -33,7 +33,7 @@ const fs_1 = __importDefault(require("fs"));
33
33
  const pyth_price_listener_1 = require("../pyth-price-listener");
34
34
  const controller_1 = require("../controller");
35
35
  const sui_1 = require("./sui");
36
- const sui_js_1 = require("@mysten/sui.js");
36
+ const ed25519_1 = require("@mysten/sui.js/keypairs/ed25519");
37
37
  exports.default = {
38
38
  command: "sui",
39
39
  describe: "Run price pusher for sui. Most of the arguments below are" +
@@ -101,7 +101,7 @@ exports.default = {
101
101
  },
102
102
  });
103
103
  const mnemonic = fs_1.default.readFileSync(mnemonicFile, "utf-8").trim();
104
- const keypair = sui_js_1.Ed25519Keypair.deriveKeypair(mnemonic, `m/44'/784'/${accountIndex}'/0'/0'`);
104
+ const keypair = ed25519_1.Ed25519Keypair.deriveKeypair(mnemonic, `m/44'/784'/${accountIndex}'/0'/0'`);
105
105
  console.log(`Pushing updates from wallet address: ${keypair
106
106
  .getPublicKey()
107
107
  .toSuiAddress()}`);
package/lib/sui/sui.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { ChainPriceListener, IPricePusher, PriceInfo, PriceItem } from "../interface";
2
2
  import { DurationInSeconds } from "../utils";
3
3
  import { PriceServiceConnection } from "@pythnetwork/price-service-client";
4
- import { JsonRpcProvider, Ed25519Keypair, RawSigner, SuiObjectRef, ObjectId } from "@mysten/sui.js";
5
4
  import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
5
+ import { Ed25519Keypair } from "@mysten/sui.js/keypairs/ed25519";
6
+ import { SuiClient, SuiObjectRef } from "@mysten/sui.js/client";
7
+ type ObjectId = string;
6
8
  export declare class SuiPriceListener extends ChainPriceListener {
7
9
  private pythClient;
8
10
  private provider;
@@ -27,6 +29,7 @@ export declare class SuiPriceListener extends ChainPriceListener {
27
29
  */
28
30
  export declare class SuiPricePusher implements IPricePusher {
29
31
  private readonly signer;
32
+ private readonly provider;
30
33
  private priceServiceConnection;
31
34
  private pythPackageId;
32
35
  private pythStateId;
@@ -35,7 +38,7 @@ export declare class SuiPricePusher implements IPricePusher {
35
38
  private gasBudget;
36
39
  private gasPool;
37
40
  private pythClient;
38
- constructor(signer: RawSigner, priceServiceConnection: PriceServiceConnection, pythPackageId: string, pythStateId: string, wormholePackageId: string, wormholeStateId: string, endpoint: string, keypair: Ed25519Keypair, gasBudget: number, gasPool: SuiObjectRef[], pythClient: SuiPythClient);
41
+ constructor(signer: Ed25519Keypair, provider: SuiClient, priceServiceConnection: PriceServiceConnection, pythPackageId: string, pythStateId: string, wormholePackageId: string, wormholeStateId: string, endpoint: string, keypair: Ed25519Keypair, gasBudget: number, gasPool: SuiObjectRef[], pythClient: SuiPythClient);
39
42
  /**
40
43
  * getPackageId returns the latest package id that the object belongs to. Use this to
41
44
  * fetch the latest package id for a given object id and handle package upgrades automatically.
@@ -43,7 +46,7 @@ export declare class SuiPricePusher implements IPricePusher {
43
46
  * @param objectId
44
47
  * @returns package id
45
48
  */
46
- static getPackageId(provider: JsonRpcProvider, objectId: ObjectId): Promise<ObjectId>;
49
+ static getPackageId(provider: SuiClient, objectId: ObjectId): Promise<ObjectId>;
47
50
  /**
48
51
  * Create a price pusher with a pool of `numGasObjects` gas coins that will be used to send transactions.
49
52
  * The gas coins of the wallet for the provided keypair will be merged and then evenly split into `numGasObjects`.
@@ -60,4 +63,5 @@ export declare class SuiPricePusher implements IPricePusher {
60
63
  private static splitGasCoinEqually;
61
64
  private static mergeGasCoinsIntoOne;
62
65
  }
66
+ export {};
63
67
  //# sourceMappingURL=sui.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../src/sui/sui.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,eAAe,EAEf,cAAc,EACd,SAAS,EAGT,YAAY,EAKZ,QAAQ,EACT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,QAAQ,CAAkB;gBAGhC,WAAW,EAAE,QAAQ,EACrB,eAAe,EAAE,QAAQ,EACzB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAWG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA+C3E;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAe,YAAW,YAAY;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,eAAe;IAGvB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;gBAVD,MAAM,EAAE,SAAS,EAC1B,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,EAAE,aAAa;IAGnC;;;;;;OAMG;WACU,YAAY,CACvB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,QAAQ,CAAC;IAuBpB;;;OAGG;WACU,0BAA0B,CACrC,sBAAsB,EAAE,sBAAsB,EAC9C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC;IA8CpB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;IA0ChB,iGAAiG;YACnF,qBAAqB;IAMnC,sEAAsE;YACxD,oBAAoB;mBAwDb,iBAAiB;mBAuCjB,yBAAyB;mBAoBzB,cAAc;mBAiCd,mBAAmB;mBAsCnB,oBAAoB;CA+D1C"}
1
+ {"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../src/sui/sui.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAC;AAOhF,KAAK,QAAQ,GAAG,MAAM,CAAC;AAGvB,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,QAAQ,CAAY;gBAG1B,WAAW,EAAE,QAAQ,EACrB,eAAe,EAAE,QAAQ,EACzB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAWG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA2C3E;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAe,YAAW,YAAY;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,eAAe;IAGvB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;gBAXD,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,SAAS,EAC5B,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,EAAE,aAAa;IAGnC;;;;;;OAMG;WACU,YAAY,CACvB,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,QAAQ,CAAC;IAyBpB;;;OAGG;WACU,0BAA0B,CACrC,sBAAsB,EAAE,sBAAsB,EAC9C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC;IA6CpB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;IA0ChB,iGAAiG;YACnF,qBAAqB;IAMnC,sEAAsE;YACxD,oBAAoB;mBAyDb,iBAAiB;mBA4CjB,yBAAyB;mBAoBzB,cAAc;mBAiCd,mBAAmB;mBAwCnB,oBAAoB;CA4D1C"}
package/lib/sui/sui.js CHANGED
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SuiPricePusher = exports.SuiPriceListener = void 0;
4
4
  const interface_1 = require("../interface");
5
- const sui_js_1 = require("@mysten/sui.js");
6
5
  const pyth_sui_js_1 = require("@pythnetwork/pyth-sui-js");
6
+ const transactions_1 = require("@mysten/sui.js/transactions");
7
+ const client_1 = require("@mysten/sui.js/client");
7
8
  const GAS_FEE_FOR_SPLIT = 2_000_000_000;
8
9
  // TODO: read this from on chain config
9
10
  const MAX_NUM_GAS_OBJECTS_IN_PTB = 256;
@@ -13,7 +14,7 @@ class SuiPriceListener extends interface_1.ChainPriceListener {
13
14
  provider;
14
15
  constructor(pythStateId, wormholeStateId, endpoint, priceItems, config) {
15
16
  super("sui", config.pollingFrequency, priceItems);
16
- this.provider = new sui_js_1.JsonRpcProvider(new sui_js_1.Connection({ fullnode: endpoint }));
17
+ this.provider = new client_1.SuiClient({ url: endpoint });
17
18
  this.pythClient = new pyth_sui_js_1.SuiPythClient(this.provider, pythStateId, wormholeStateId);
18
19
  }
19
20
  async getOnChainPriceInfo(priceId) {
@@ -27,17 +28,18 @@ class SuiPriceListener extends interface_1.ChainPriceListener {
27
28
  id: priceInfoObjectId,
28
29
  options: { showContent: true },
29
30
  });
30
- if (priceInfoObject.data === undefined ||
31
- priceInfoObject.data.content === undefined)
31
+ if (!priceInfoObject.data || !priceInfoObject.data.content)
32
32
  throw new Error("Price not found on chain for price id " + priceId);
33
33
  if (priceInfoObject.data.content.dataType !== "moveObject")
34
34
  throw new Error("fetched object datatype should be moveObject");
35
- const { magnitude, negative } = priceInfoObject.data.content.fields.price_info.fields.price_feed.fields
36
- .price.fields.price.fields;
37
- const conf = priceInfoObject.data.content.fields.price_info.fields.price_feed.fields
38
- .price.fields.conf;
39
- const timestamp = priceInfoObject.data.content.fields.price_info.fields.price_feed.fields
40
- .price.fields.timestamp;
35
+ const priceInfo =
36
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
37
+ // @ts-ignore
38
+ priceInfoObject.data.content.fields.price_info.fields.price_feed.fields
39
+ .price.fields;
40
+ const { magnitude, negative } = priceInfo.price.fields;
41
+ const conf = priceInfo.conf;
42
+ const timestamp = priceInfo.timestamp;
41
43
  return {
42
44
  price: negative ? "-" + magnitude : magnitude,
43
45
  conf,
@@ -68,6 +70,7 @@ exports.SuiPriceListener = SuiPriceListener;
68
70
  */
69
71
  class SuiPricePusher {
70
72
  signer;
73
+ provider;
71
74
  priceServiceConnection;
72
75
  pythPackageId;
73
76
  pythStateId;
@@ -76,8 +79,9 @@ class SuiPricePusher {
76
79
  gasBudget;
77
80
  gasPool;
78
81
  pythClient;
79
- constructor(signer, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient) {
82
+ constructor(signer, provider, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient) {
80
83
  this.signer = signer;
84
+ this.provider = provider;
81
85
  this.priceServiceConnection = priceServiceConnection;
82
86
  this.pythPackageId = pythPackageId;
83
87
  this.pythStateId = pythStateId;
@@ -109,6 +113,8 @@ class SuiPricePusher {
109
113
  throw new Error("not move object");
110
114
  });
111
115
  if ("upgrade_cap" in state) {
116
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
117
+ // @ts-ignore
112
118
  return state.upgrade_cap.fields.package;
113
119
  }
114
120
  throw new Error("upgrade_cap not found");
@@ -121,13 +127,12 @@ class SuiPricePusher {
121
127
  if (numGasObjects > MAX_NUM_OBJECTS_IN_ARGUMENT) {
122
128
  throw new Error(`numGasObjects cannot be greater than ${MAX_NUM_OBJECTS_IN_ARGUMENT} until we implement split chunking`);
123
129
  }
124
- const provider = new sui_js_1.JsonRpcProvider(new sui_js_1.Connection({ fullnode: endpoint }));
125
- const signer = new sui_js_1.RawSigner(keypair, provider);
130
+ const provider = new client_1.SuiClient({ url: endpoint });
126
131
  const pythPackageId = await SuiPricePusher.getPackageId(provider, pythStateId);
127
132
  const wormholePackageId = await SuiPricePusher.getPackageId(provider, wormholeStateId);
128
- const gasPool = await SuiPricePusher.initializeGasPool(signer, numGasObjects);
133
+ const gasPool = await SuiPricePusher.initializeGasPool(keypair, provider, numGasObjects);
129
134
  const pythClient = new pyth_sui_js_1.SuiPythClient(provider, pythStateId, wormholeStateId);
130
- return new SuiPricePusher(signer, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient);
135
+ return new SuiPricePusher(keypair, provider, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient);
131
136
  }
132
137
  async updatePriceFeed(priceIds, pubTimesToPush) {
133
138
  if (priceIds.length === 0) {
@@ -148,7 +153,7 @@ class SuiPricePusher {
148
153
  throw new Error(`Expected a single VAA for all priceIds ${priceIdChunk} but received ${vaas.length} VAAs: ${vaas}`);
149
154
  }
150
155
  const vaa = vaas[0];
151
- const tx = new sui_js_1.TransactionBlock();
156
+ const tx = new transactions_1.TransactionBlock();
152
157
  await this.pythClient.updatePriceFeeds(tx, [Buffer.from(vaa, "base64")], priceIdChunk);
153
158
  txBlocks.push(tx);
154
159
  }));
@@ -169,14 +174,15 @@ class SuiPricePusher {
169
174
  try {
170
175
  tx.setGasPayment([gasObject]);
171
176
  tx.setGasBudget(this.gasBudget);
172
- const result = await this.signer.signAndExecuteTransactionBlock({
177
+ const result = await this.provider.signAndExecuteTransactionBlock({
178
+ signer: this.signer,
173
179
  transactionBlock: tx,
174
180
  options: {
175
181
  showEffects: true,
176
182
  },
177
183
  });
178
- nextGasObject = (0, sui_js_1.getTransactionEffects)(result)
179
- ?.mutated?.map((obj) => obj.reference)
184
+ nextGasObject = result.effects?.mutated
185
+ ?.map((obj) => obj.reference)
180
186
  .find((ref) => ref.objectId === gasObject.objectId);
181
187
  console.log("Successfully updated price with transaction digest ", result.digest);
182
188
  }
@@ -189,7 +195,7 @@ class SuiPricePusher {
189
195
  }
190
196
  else {
191
197
  // Refresh the coin object here in case the error is caused by an object version mismatch.
192
- nextGasObject = await SuiPricePusher.tryRefreshObjectReference(this.signer.provider, gasObject);
198
+ nextGasObject = await SuiPricePusher.tryRefreshObjectReference(this.provider, gasObject);
193
199
  }
194
200
  console.error(e);
195
201
  if ("data" in e) {
@@ -203,10 +209,10 @@ class SuiPricePusher {
203
209
  }
204
210
  // This function will smash all coins owned by the signer into one, and then
205
211
  // split them equally into numGasObjects.
206
- static async initializeGasPool(signer, numGasObjects) {
207
- const signerAddress = await signer.getAddress();
208
- const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne(signer, signerAddress);
209
- const coinResult = await signer.provider.getObject({
212
+ static async initializeGasPool(signer, provider, numGasObjects) {
213
+ const signerAddress = await signer.toSuiAddress();
214
+ const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne(signer, provider, signerAddress);
215
+ const coinResult = await provider.getObject({
210
216
  id: consolidatedCoin.objectId,
211
217
  options: { showContent: true },
212
218
  });
@@ -214,12 +220,14 @@ class SuiPricePusher {
214
220
  if (coinResult.data &&
215
221
  coinResult.data.content &&
216
222
  coinResult.data.content.dataType == "moveObject") {
223
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
224
+ // @ts-ignore
217
225
  balance = coinResult.data.content.fields.balance;
218
226
  }
219
227
  else
220
228
  throw new Error("Bad coin object");
221
229
  const splitAmount = (BigInt(balance) - BigInt(GAS_FEE_FOR_SPLIT)) / BigInt(numGasObjects);
222
- const gasPool = await SuiPricePusher.splitGasCoinEqually(signer, signerAddress, Number(splitAmount), numGasObjects, consolidatedCoin);
230
+ const gasPool = await SuiPricePusher.splitGasCoinEqually(signer, provider, signerAddress, Number(splitAmount), numGasObjects, consolidatedCoin);
223
231
  console.log("Gas pool is filled with coins: ", gasPool);
224
232
  return gasPool;
225
233
  }
@@ -268,28 +276,29 @@ class SuiPricePusher {
268
276
  }
269
277
  return [...coins].map((item) => JSON.parse(item));
270
278
  }
271
- static async splitGasCoinEqually(signer, signerAddress, splitAmount, numGasObjects, gasCoin) {
279
+ static async splitGasCoinEqually(signer, provider, signerAddress, splitAmount, numGasObjects, gasCoin) {
272
280
  // TODO: implement chunking if numGasObjects exceeds MAX_NUM_CREATED_OBJECTS
273
- const tx = new sui_js_1.TransactionBlock();
281
+ const tx = new transactions_1.TransactionBlock();
274
282
  const coins = tx.splitCoins(tx.gas, Array.from({ length: numGasObjects }, () => tx.pure(splitAmount)));
275
283
  tx.transferObjects(Array.from({ length: numGasObjects }, (_, i) => coins[i]), tx.pure(signerAddress));
276
284
  tx.setGasPayment([gasCoin]);
277
- const result = await signer.signAndExecuteTransactionBlock({
285
+ const result = await provider.signAndExecuteTransactionBlock({
286
+ signer,
278
287
  transactionBlock: tx,
279
288
  options: { showEffects: true },
280
289
  });
281
- const error = (0, sui_js_1.getExecutionStatusError)(result);
290
+ const error = result?.effects?.status.error;
282
291
  if (error) {
283
292
  throw new Error(`Failed to initialize gas pool: ${error}. Try re-running the script`);
284
293
  }
285
- const newCoins = (0, sui_js_1.getCreatedObjects)(result).map((obj) => obj.reference);
294
+ const newCoins = result.effects.created.map((obj) => obj.reference);
286
295
  if (newCoins.length !== numGasObjects) {
287
296
  throw new Error(`Failed to initialize gas pool. Expected ${numGasObjects}, got: ${newCoins}`);
288
297
  }
289
298
  return newCoins;
290
299
  }
291
- static async mergeGasCoinsIntoOne(signer, owner) {
292
- const gasCoins = await SuiPricePusher.getAllGasCoins(signer.provider, owner);
300
+ static async mergeGasCoinsIntoOne(signer, provider, owner) {
301
+ const gasCoins = await SuiPricePusher.getAllGasCoins(provider, owner);
293
302
  // skip merging if there is only one coin
294
303
  if (gasCoins.length === 1) {
295
304
  return gasCoins[0];
@@ -298,7 +307,7 @@ class SuiPricePusher {
298
307
  let finalCoin;
299
308
  const lockedAddresses = new Set();
300
309
  for (let i = 0; i < gasCoinsChunks.length; i++) {
301
- const mergeTx = new sui_js_1.TransactionBlock();
310
+ const mergeTx = new transactions_1.TransactionBlock();
302
311
  let coins = gasCoinsChunks[i];
303
312
  coins = coins.filter((coin) => !lockedAddresses.has(coin.objectId));
304
313
  if (finalCoin) {
@@ -307,7 +316,8 @@ class SuiPricePusher {
307
316
  mergeTx.setGasPayment(coins);
308
317
  let mergeResult;
309
318
  try {
310
- mergeResult = await signer.signAndExecuteTransactionBlock({
319
+ mergeResult = await provider.signAndExecuteTransactionBlock({
320
+ signer,
311
321
  transactionBlock: mergeTx,
312
322
  options: { showEffects: true },
313
323
  });
@@ -325,11 +335,11 @@ class SuiPricePusher {
325
335
  }
326
336
  throw e;
327
337
  }
328
- const error = (0, sui_js_1.getExecutionStatusError)(mergeResult);
338
+ const error = mergeResult?.effects?.status.error;
329
339
  if (error) {
330
340
  throw new Error(`Failed to merge coins when initializing gas pool: ${error}. Try re-running the script`);
331
341
  }
332
- finalCoin = (0, sui_js_1.getTransactionEffects)(mergeResult).mutated.map((obj) => obj.reference)[0];
342
+ finalCoin = mergeResult.effects.mutated.map((obj) => obj.reference)[0];
333
343
  }
334
344
  return finalCoin;
335
345
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pythnetwork/price-pusher",
3
- "version": "6.1.0",
3
+ "version": "6.3.1",
4
4
  "description": "Pyth Price Pusher",
5
5
  "homepage": "https://pyth.network",
6
6
  "main": "lib/index.js",
@@ -45,24 +45,25 @@
45
45
  "@typescript-eslint/eslint-plugin": "^5.20.0",
46
46
  "@typescript-eslint/parser": "^5.20.0",
47
47
  "eslint": "^8.13.0",
48
- "jest": "^27.5.1",
48
+ "jest": "^29.7.0",
49
49
  "prettier": "^2.6.2",
50
- "ts-jest": "^27.1.4",
51
- "typescript": "^4.6.3"
50
+ "ts-jest": "^29.1.1",
51
+ "typescript": "^5.3.3"
52
52
  },
53
53
  "dependencies": {
54
54
  "@injectivelabs/sdk-ts": "1.10.72",
55
- "@mysten/sui.js": "^0.37.1",
55
+ "@mysten/sui.js": "^0.49.1",
56
56
  "@pythnetwork/price-service-client": "*",
57
57
  "@pythnetwork/pyth-sdk-solidity": "*",
58
58
  "@pythnetwork/pyth-sui-js": "*",
59
59
  "@truffle/hdwallet-provider": "^2.1.3",
60
60
  "aptos": "^1.8.5",
61
61
  "joi": "^17.6.0",
62
+ "near-api-js": "^3.0.2",
62
63
  "web3": "^1.8.1",
63
64
  "web3-eth-contract": "^1.8.1",
64
65
  "yaml": "^2.1.1",
65
66
  "yargs": "^17.5.1"
66
67
  },
67
- "gitHead": "1be8a02b94d2a09e5284da72e57eb0eb3943d3ae"
68
+ "gitHead": "f14dd35d1abe0dc5e35752db4a77f4781d0a5c83"
68
69
  }