@pythnetwork/price-pusher 6.8.0 → 7.0.0-alpha

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.
Files changed (56) hide show
  1. package/README.md +26 -14
  2. package/lib/aptos/aptos.d.ts +5 -2
  3. package/lib/aptos/aptos.d.ts.map +1 -1
  4. package/lib/aptos/aptos.js +19 -19
  5. package/lib/aptos/command.d.ts +3 -0
  6. package/lib/aptos/command.d.ts.map +1 -1
  7. package/lib/aptos/command.js +12 -14
  8. package/lib/controller.d.ts +3 -1
  9. package/lib/controller.d.ts.map +1 -1
  10. package/lib/controller.js +11 -4
  11. package/lib/evm/command.d.ts +3 -0
  12. package/lib/evm/command.d.ts.map +1 -1
  13. package/lib/evm/command.js +14 -16
  14. package/lib/evm/custom-gas-station.d.ts +4 -2
  15. package/lib/evm/custom-gas-station.d.ts.map +1 -1
  16. package/lib/evm/custom-gas-station.js +7 -6
  17. package/lib/evm/evm.d.ts +7 -3
  18. package/lib/evm/evm.d.ts.map +1 -1
  19. package/lib/evm/evm.js +25 -24
  20. package/lib/injective/command.d.ts +3 -0
  21. package/lib/injective/command.d.ts.map +1 -1
  22. package/lib/injective/command.js +11 -13
  23. package/lib/injective/injective.d.ts +5 -2
  24. package/lib/injective/injective.d.ts.map +1 -1
  25. package/lib/injective/injective.js +22 -22
  26. package/lib/interface.d.ts +1 -2
  27. package/lib/interface.d.ts.map +1 -1
  28. package/lib/interface.js +1 -4
  29. package/lib/near/command.d.ts +3 -0
  30. package/lib/near/command.d.ts.map +1 -1
  31. package/lib/near/command.js +14 -13
  32. package/lib/near/near.d.ts +5 -2
  33. package/lib/near/near.d.ts.map +1 -1
  34. package/lib/near/near.js +19 -17
  35. package/lib/options.d.ts +9 -0
  36. package/lib/options.d.ts.map +1 -1
  37. package/lib/options.js +28 -1
  38. package/lib/price-config.d.ts +2 -1
  39. package/lib/price-config.d.ts.map +1 -1
  40. package/lib/price-config.js +4 -6
  41. package/lib/pyth-price-listener.d.ts +3 -1
  42. package/lib/pyth-price-listener.d.ts.map +1 -1
  43. package/lib/pyth-price-listener.js +4 -2
  44. package/lib/solana/command.d.ts +5 -1
  45. package/lib/solana/command.d.ts.map +1 -1
  46. package/lib/solana/command.js +16 -18
  47. package/lib/solana/solana.d.ts +9 -5
  48. package/lib/solana/solana.d.ts.map +1 -1
  49. package/lib/solana/solana.js +27 -18
  50. package/lib/sui/command.d.ts +3 -0
  51. package/lib/sui/command.d.ts.map +1 -1
  52. package/lib/sui/command.js +12 -14
  53. package/lib/sui/sui.d.ts +6 -3
  54. package/lib/sui/sui.d.ts.map +1 -1
  55. package/lib/sui/sui.js +31 -36
  56. package/package.json +21 -11
package/lib/sui/sui.js CHANGED
@@ -12,10 +12,12 @@ const MAX_NUM_OBJECTS_IN_ARGUMENT = 510;
12
12
  class SuiPriceListener extends interface_1.ChainPriceListener {
13
13
  pythClient;
14
14
  provider;
15
- constructor(pythStateId, wormholeStateId, endpoint, priceItems, config) {
16
- super("sui", config.pollingFrequency, priceItems);
15
+ logger;
16
+ constructor(pythStateId, wormholeStateId, endpoint, priceItems, logger, config) {
17
+ super(config.pollingFrequency, priceItems);
17
18
  this.provider = new client_1.SuiClient({ url: endpoint });
18
19
  this.pythClient = new pyth_sui_js_1.SuiPythClient(this.provider, pythStateId, wormholeStateId);
20
+ this.logger = logger;
19
21
  }
20
22
  async getOnChainPriceInfo(priceId) {
21
23
  try {
@@ -46,9 +48,8 @@ class SuiPriceListener extends interface_1.ChainPriceListener {
46
48
  publishTime: Number(timestamp),
47
49
  };
48
50
  }
49
- catch (e) {
50
- console.error(`Polling Sui on-chain price for ${priceId} failed. Error:`);
51
- console.error(e);
51
+ catch (err) {
52
+ this.logger.error(err, `Polling Sui on-chain price for ${priceId} failed.`);
52
53
  return undefined;
53
54
  }
54
55
  }
@@ -71,6 +72,7 @@ exports.SuiPriceListener = SuiPriceListener;
71
72
  class SuiPricePusher {
72
73
  signer;
73
74
  provider;
75
+ logger;
74
76
  priceServiceConnection;
75
77
  pythPackageId;
76
78
  pythStateId;
@@ -79,9 +81,10 @@ class SuiPricePusher {
79
81
  gasBudget;
80
82
  gasPool;
81
83
  pythClient;
82
- constructor(signer, provider, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient) {
84
+ constructor(signer, provider, logger, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient) {
83
85
  this.signer = signer;
84
86
  this.provider = provider;
87
+ this.logger = logger;
85
88
  this.priceServiceConnection = priceServiceConnection;
86
89
  this.pythPackageId = pythPackageId;
87
90
  this.pythStateId = pythStateId;
@@ -123,16 +126,16 @@ class SuiPricePusher {
123
126
  * Create a price pusher with a pool of `numGasObjects` gas coins that will be used to send transactions.
124
127
  * The gas coins of the wallet for the provided keypair will be merged and then evenly split into `numGasObjects`.
125
128
  */
126
- static async createWithAutomaticGasPool(priceServiceConnection, pythStateId, wormholeStateId, endpoint, keypair, gasBudget, numGasObjects, ignoreGasObjects) {
129
+ static async createWithAutomaticGasPool(priceServiceConnection, logger, pythStateId, wormholeStateId, endpoint, keypair, gasBudget, numGasObjects, ignoreGasObjects) {
127
130
  if (numGasObjects > MAX_NUM_OBJECTS_IN_ARGUMENT) {
128
131
  throw new Error(`numGasObjects cannot be greater than ${MAX_NUM_OBJECTS_IN_ARGUMENT} until we implement split chunking`);
129
132
  }
130
133
  const provider = new client_1.SuiClient({ url: endpoint });
131
134
  const pythPackageId = await SuiPricePusher.getPackageId(provider, pythStateId);
132
135
  const wormholePackageId = await SuiPricePusher.getPackageId(provider, wormholeStateId);
133
- const gasPool = await SuiPricePusher.initializeGasPool(keypair, provider, numGasObjects, ignoreGasObjects);
136
+ const gasPool = await SuiPricePusher.initializeGasPool(keypair, provider, numGasObjects, ignoreGasObjects, logger);
134
137
  const pythClient = new pyth_sui_js_1.SuiPythClient(provider, pythStateId, wormholeStateId);
135
- return new SuiPricePusher(keypair, provider, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient);
138
+ return new SuiPricePusher(keypair, provider, logger, priceServiceConnection, pythPackageId, pythStateId, wormholePackageId, wormholeStateId, endpoint, keypair, gasBudget, gasPool, pythClient);
136
139
  }
137
140
  async updatePriceFeed(priceIds, pubTimesToPush) {
138
141
  if (priceIds.length === 0) {
@@ -141,7 +144,7 @@ class SuiPricePusher {
141
144
  if (priceIds.length !== pubTimesToPush.length)
142
145
  throw new Error("Invalid arguments");
143
146
  if (this.gasPool.length === 0) {
144
- console.warn("Skipping update: no available gas coin.");
147
+ this.logger.warn("Skipping update: no available gas coin.");
145
148
  return;
146
149
  }
147
150
  // 3 price feeds per transaction is the optimal number for gas cost.
@@ -167,7 +170,7 @@ class SuiPricePusher {
167
170
  async sendTransactionBlock(tx) {
168
171
  const gasObject = this.gasPool.shift();
169
172
  if (gasObject === undefined) {
170
- console.warn("No available gas coin. Skipping push.");
173
+ this.logger.warn("No available gas coin. Skipping push.");
171
174
  return;
172
175
  }
173
176
  let nextGasObject = undefined;
@@ -184,24 +187,20 @@ class SuiPricePusher {
184
187
  nextGasObject = result.effects?.mutated
185
188
  ?.map((obj) => obj.reference)
186
189
  .find((ref) => ref.objectId === gasObject.objectId);
187
- console.log("Successfully updated price with transaction digest ", result.digest);
190
+ this.logger.info({ hash: result.digest }, "Successfully updated price with transaction digest");
188
191
  }
189
- catch (e) {
190
- console.log("Error when signAndExecuteTransactionBlock");
191
- if (String(e).includes("Balance of gas object") ||
192
- String(e).includes("GasBalanceTooLow")) {
192
+ catch (err) {
193
+ if (String(err).includes("Balance of gas object") ||
194
+ String(err).includes("GasBalanceTooLow")) {
195
+ this.logger.error(err, "Insufficient gas balance");
193
196
  // If the error is caused by insufficient gas, we should panic
194
- throw e;
197
+ throw err;
195
198
  }
196
199
  else {
200
+ this.logger.error(err, "Failed to update price. Trying to refresh gas object references.");
197
201
  // Refresh the coin object here in case the error is caused by an object version mismatch.
198
202
  nextGasObject = await SuiPricePusher.tryRefreshObjectReference(this.provider, gasObject);
199
203
  }
200
- console.error(e);
201
- if ("data" in e) {
202
- console.error("Error has .data field:");
203
- console.error(JSON.stringify(e.data));
204
- }
205
204
  }
206
205
  if (nextGasObject !== undefined) {
207
206
  this.gasPool.push(nextGasObject);
@@ -211,13 +210,12 @@ class SuiPricePusher {
211
210
  // split them equally into numGasObjects.
212
211
  // ignoreGasObjects is a list of gas objects that will be ignored during the
213
212
  // merging -- use this to store any locked objects on initialization.
214
- static async initializeGasPool(signer, provider, numGasObjects, ignoreGasObjects) {
213
+ static async initializeGasPool(signer, provider, numGasObjects, ignoreGasObjects, logger) {
215
214
  const signerAddress = await signer.toSuiAddress();
216
215
  if (ignoreGasObjects.length > 0) {
217
- console.log("Ignoring some gas objects for coin merging:");
218
- console.log(ignoreGasObjects);
216
+ logger.info({ ignoreGasObjects }, "Ignoring some gas objects for coin merging");
219
217
  }
220
- const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne(signer, provider, signerAddress, ignoreGasObjects);
218
+ const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne(signer, provider, signerAddress, ignoreGasObjects, logger);
221
219
  const coinResult = await provider.getObject({
222
220
  id: consolidatedCoin.objectId,
223
221
  options: { showContent: true },
@@ -234,7 +232,7 @@ class SuiPricePusher {
234
232
  throw new Error("Bad coin object");
235
233
  const splitAmount = (BigInt(balance) - BigInt(GAS_FEE_FOR_SPLIT)) / BigInt(numGasObjects);
236
234
  const gasPool = await SuiPricePusher.splitGasCoinEqually(signer, provider, signerAddress, Number(splitAmount), numGasObjects, consolidatedCoin);
237
- console.log("Gas pool is filled with coins: ", gasPool);
235
+ logger.info({ gasPool }, "Gas pool is filled with coins");
238
236
  return gasPool;
239
237
  }
240
238
  // Attempt to refresh the version of the provided object reference to point to the current version
@@ -303,7 +301,7 @@ class SuiPricePusher {
303
301
  }
304
302
  return newCoins;
305
303
  }
306
- static async mergeGasCoinsIntoOne(signer, provider, owner, initialLockedAddresses) {
304
+ static async mergeGasCoinsIntoOne(signer, provider, owner, initialLockedAddresses, logger) {
307
305
  const gasCoins = await SuiPricePusher.getAllGasCoins(provider, owner);
308
306
  // skip merging if there is only one coin
309
307
  if (gasCoins.length === 1) {
@@ -329,13 +327,10 @@ class SuiPricePusher {
329
327
  options: { showEffects: true },
330
328
  });
331
329
  }
332
- catch (e) {
333
- console.log("Merge transaction failed with error:");
334
- console.log(e);
335
- console.log(e.data);
336
- console.log(JSON.stringify(e));
337
- if (String(e).includes("quorum of validators because of locked objects. Retried a conflicting transaction")) {
338
- Object.values(e.data).forEach((lockedObjects) => {
330
+ catch (err) {
331
+ logger.error(err, "Merge transaction failed with error");
332
+ if (String(err).includes("quorum of validators because of locked objects. Retried a conflicting transaction")) {
333
+ Object.values(err.data).forEach((lockedObjects) => {
339
334
  lockedObjects.forEach((lockedObject) => {
340
335
  lockedAddresses.add(lockedObject[0]);
341
336
  });
@@ -344,7 +339,7 @@ class SuiPricePusher {
344
339
  i--;
345
340
  continue;
346
341
  }
347
- throw e;
342
+ throw err;
348
343
  }
349
344
  const error = mergeResult?.effects?.status.error;
350
345
  if (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pythnetwork/price-pusher",
3
- "version": "6.8.0",
3
+ "version": "7.0.0-alpha",
4
4
  "description": "Pyth Price Pusher",
5
5
  "homepage": "https://pyth.network",
6
6
  "main": "lib/index.js",
@@ -26,9 +26,9 @@
26
26
  "lint": "eslint src/",
27
27
  "start": "node lib/index.js",
28
28
  "dev": "ts-node src/index.ts",
29
- "prepublishOnly": "npm run build && npm test && npm run lint",
30
- "preversion": "npm run lint",
31
- "version": "npm run format && git add -A src"
29
+ "prepublishOnly": "pnpm run build && pnpm test && pnpm run lint",
30
+ "preversion": "pnpm run lint",
31
+ "version": "pnpm run format && git add -A src"
32
32
  },
33
33
  "keywords": [
34
34
  "pyth",
@@ -42,30 +42,40 @@
42
42
  "@types/ethereum-protocol": "^1.0.2",
43
43
  "@types/jest": "^27.4.1",
44
44
  "@types/yargs": "^17.0.10",
45
- "@typescript-eslint/eslint-plugin": "^5.20.0",
46
- "@typescript-eslint/parser": "^5.20.0",
45
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
46
+ "@typescript-eslint/parser": "^6.0.0",
47
47
  "eslint": "^8.13.0",
48
48
  "jest": "^29.7.0",
49
+ "pino-pretty": "^11.2.1",
49
50
  "prettier": "^2.6.2",
50
51
  "ts-jest": "^29.1.1",
52
+ "ts-node": "^10.9.1",
51
53
  "typescript": "^5.3.3"
52
54
  },
53
55
  "dependencies": {
56
+ "@coral-xyz/anchor": "^0.30.0",
57
+ "@injectivelabs/networks": "^1.14.6",
54
58
  "@injectivelabs/sdk-ts": "1.10.72",
55
59
  "@mysten/sui.js": "^0.49.1",
56
- "@pythnetwork/price-service-client": "*",
57
- "@pythnetwork/pyth-sdk-solidity": "*",
58
- "@pythnetwork/pyth-solana-receiver": "*",
59
- "@pythnetwork/pyth-sui-js": "*",
60
+ "@pythnetwork/price-service-client": "1.9.0",
61
+ "@pythnetwork/price-service-sdk": "^1.7.1",
62
+ "@pythnetwork/pyth-sdk-solidity": "3.1.0",
63
+ "@pythnetwork/pyth-solana-receiver": "0.8.0",
64
+ "@pythnetwork/pyth-sui-js": "2.0.0",
65
+ "@pythnetwork/solana-utils": "0.4.1",
66
+ "@solana/web3.js": "^1.93.0",
60
67
  "@truffle/hdwallet-provider": "^2.1.3",
68
+ "@types/pino": "^7.0.5",
61
69
  "aptos": "^1.8.5",
62
70
  "jito-ts": "^3.0.1",
63
71
  "joi": "^17.6.0",
64
72
  "near-api-js": "^3.0.2",
73
+ "pino": "^9.2.0",
65
74
  "web3": "^1.8.1",
75
+ "web3-core": "^1.8.1",
66
76
  "web3-eth-contract": "^1.8.1",
67
77
  "yaml": "^2.1.1",
68
78
  "yargs": "^17.5.1"
69
79
  },
70
- "gitHead": "641a4bdd6306ccb62ece63b800f9727f54f816df"
80
+ "gitHead": "40a63bf8f80d9f929eeddfb7c4e4f9d0e56d93fb"
71
81
  }