@pythnetwork/price-pusher 10.0.0 → 10.3.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.
Files changed (128) hide show
  1. package/README.md +31 -3
  2. package/{lib/aptos/aptos.js → dist/aptos/aptos.cjs} +80 -76
  3. package/{lib → dist}/aptos/aptos.d.ts +5 -5
  4. package/{lib/aptos/balance-tracker.js → dist/aptos/balance-tracker.cjs} +37 -25
  5. package/{lib → dist}/aptos/balance-tracker.d.ts +9 -9
  6. package/dist/aptos/command.cjs +161 -0
  7. package/{lib → dist}/aptos/command.d.ts +1 -2
  8. package/dist/common.cjs +4 -0
  9. package/{lib → dist}/common.d.ts +0 -1
  10. package/{lib/controller.js → dist/controller.cjs} +36 -33
  11. package/{lib → dist}/controller.d.ts +5 -6
  12. package/dist/evm/balance-tracker.cjs +58 -0
  13. package/{lib → dist}/evm/balance-tracker.d.ts +10 -10
  14. package/dist/evm/command.cjs +205 -0
  15. package/{lib → dist}/evm/command.d.ts +1 -2
  16. package/dist/evm/custom-gas-station.cjs +54 -0
  17. package/{lib → dist}/evm/custom-gas-station.d.ts +1 -2
  18. package/dist/evm/evm.cjs +287 -0
  19. package/{lib → dist}/evm/evm.d.ts +8 -7
  20. package/{lib/evm/pyth-abi.js → dist/evm/pyth-abi.cjs} +181 -160
  21. package/{lib → dist}/evm/pyth-abi.d.ts +0 -1
  22. package/dist/evm/pyth-contract.cjs +17 -0
  23. package/{lib → dist}/evm/pyth-contract.d.ts +3 -4
  24. package/dist/evm/super-wallet.cjs +90 -0
  25. package/{lib → dist}/evm/super-wallet.d.ts +1 -2
  26. package/dist/fuel/command.cjs +135 -0
  27. package/{lib → dist}/fuel/command.d.ts +1 -2
  28. package/dist/fuel/fuel.cjs +108 -0
  29. package/{lib → dist}/fuel/fuel.d.ts +5 -5
  30. package/dist/index.cjs +25 -0
  31. package/dist/index.d.ts +1 -0
  32. package/dist/injective/command.cjs +150 -0
  33. package/{lib → dist}/injective/command.d.ts +1 -2
  34. package/{lib/injective/injective.js → dist/injective/injective.cjs} +100 -98
  35. package/{lib → dist}/injective/injective.d.ts +7 -6
  36. package/dist/interface.cjs +142 -0
  37. package/{lib → dist}/interface.d.ts +12 -13
  38. package/dist/metrics.cjs +218 -0
  39. package/{lib → dist}/metrics.d.ts +11 -9
  40. package/dist/near/command.cjs +129 -0
  41. package/{lib → dist}/near/command.d.ts +1 -2
  42. package/dist/near/near.cjs +183 -0
  43. package/{lib → dist}/near/near.d.ts +5 -5
  44. package/dist/options.cjs +132 -0
  45. package/{lib → dist}/options.d.ts +1 -2
  46. package/dist/package.json +1 -0
  47. package/dist/price-config.cjs +104 -0
  48. package/{lib → dist}/price-config.d.ts +5 -6
  49. package/{lib/pyth-price-listener.js → dist/pyth-price-listener.cjs} +30 -24
  50. package/{lib → dist}/pyth-price-listener.d.ts +4 -4
  51. package/dist/solana/balance-tracker.cjs +60 -0
  52. package/{lib → dist}/solana/balance-tracker.d.ts +9 -9
  53. package/dist/solana/command.cjs +259 -0
  54. package/{lib → dist}/solana/command.d.ts +2 -3
  55. package/{lib/solana/solana.js → dist/solana/solana.cjs} +90 -78
  56. package/{lib → dist}/solana/solana.d.ts +6 -6
  57. package/dist/sui/balance-tracker.cjs +58 -0
  58. package/{lib → dist}/sui/balance-tracker.d.ts +9 -9
  59. package/dist/sui/command.cjs +190 -0
  60. package/{lib → dist}/sui/command.d.ts +1 -2
  61. package/{lib/sui/sui.js → dist/sui/sui.cjs} +145 -133
  62. package/{lib → dist}/sui/sui.d.ts +7 -8
  63. package/dist/ton/command.cjs +137 -0
  64. package/{lib → dist}/ton/command.d.ts +1 -2
  65. package/dist/ton/ton.cjs +103 -0
  66. package/{lib → dist}/ton/ton.d.ts +7 -6
  67. package/dist/utils.cjs +102 -0
  68. package/{lib → dist}/utils.d.ts +4 -4
  69. package/package.json +161 -20
  70. package/lib/aptos/aptos.d.ts.map +0 -1
  71. package/lib/aptos/balance-tracker.d.ts.map +0 -1
  72. package/lib/aptos/command.d.ts.map +0 -1
  73. package/lib/aptos/command.js +0 -126
  74. package/lib/common.d.ts.map +0 -1
  75. package/lib/common.js +0 -2
  76. package/lib/controller.d.ts.map +0 -1
  77. package/lib/evm/balance-tracker.d.ts.map +0 -1
  78. package/lib/evm/balance-tracker.js +0 -49
  79. package/lib/evm/command.d.ts.map +0 -1
  80. package/lib/evm/command.js +0 -178
  81. package/lib/evm/custom-gas-station.d.ts.map +0 -1
  82. package/lib/evm/custom-gas-station.js +0 -40
  83. package/lib/evm/evm.d.ts.map +0 -1
  84. package/lib/evm/evm.js +0 -270
  85. package/lib/evm/pyth-abi.d.ts.map +0 -1
  86. package/lib/evm/pyth-contract.d.ts.map +0 -1
  87. package/lib/evm/pyth-contract.js +0 -11
  88. package/lib/evm/super-wallet.d.ts.map +0 -1
  89. package/lib/evm/super-wallet.js +0 -73
  90. package/lib/fuel/command.d.ts.map +0 -1
  91. package/lib/fuel/command.js +0 -98
  92. package/lib/fuel/fuel.d.ts.map +0 -1
  93. package/lib/fuel/fuel.js +0 -101
  94. package/lib/index.d.ts +0 -3
  95. package/lib/index.d.ts.map +0 -1
  96. package/lib/index.js +0 -34
  97. package/lib/injective/command.d.ts.map +0 -1
  98. package/lib/injective/command.js +0 -119
  99. package/lib/injective/injective.d.ts.map +0 -1
  100. package/lib/interface.d.ts.map +0 -1
  101. package/lib/interface.js +0 -122
  102. package/lib/metrics.d.ts.map +0 -1
  103. package/lib/metrics.js +0 -129
  104. package/lib/near/command.d.ts.map +0 -1
  105. package/lib/near/command.js +0 -103
  106. package/lib/near/near.d.ts.map +0 -1
  107. package/lib/near/near.js +0 -168
  108. package/lib/options.d.ts.map +0 -1
  109. package/lib/options.js +0 -84
  110. package/lib/price-config.d.ts.map +0 -1
  111. package/lib/price-config.js +0 -114
  112. package/lib/pyth-price-listener.d.ts.map +0 -1
  113. package/lib/solana/balance-tracker.d.ts.map +0 -1
  114. package/lib/solana/balance-tracker.js +0 -51
  115. package/lib/solana/command.d.ts.map +0 -1
  116. package/lib/solana/command.js +0 -218
  117. package/lib/solana/solana.d.ts.map +0 -1
  118. package/lib/sui/balance-tracker.d.ts.map +0 -1
  119. package/lib/sui/balance-tracker.js +0 -49
  120. package/lib/sui/command.d.ts.map +0 -1
  121. package/lib/sui/command.js +0 -160
  122. package/lib/sui/sui.d.ts.map +0 -1
  123. package/lib/ton/command.d.ts.map +0 -1
  124. package/lib/ton/command.js +0 -99
  125. package/lib/ton/ton.d.ts.map +0 -1
  126. package/lib/ton/ton.js +0 -97
  127. package/lib/utils.d.ts.map +0 -1
  128. package/lib/utils.js +0 -61
package/README.md CHANGED
@@ -211,12 +211,12 @@ and the on-chain Pyth contract and deciding whether to push a new price. You can
211
211
 
212
212
  ### Example
213
213
 
214
- For example, to push `BTC/USD` and `BNB/USD` prices on Fantom testnet, run the following command:
214
+ For example, to push `BTC/USD` and `BNB/USD` prices on Sonic blaze testnet, run the following command:
215
215
 
216
216
  ```sh
217
217
  pnpm run dev evm \
218
- --endpoint https://endpoints.omniatech.io/v1/fantom/testnet/public \
219
- --pyth-contract-address 0x5744Cbf430D99456a0A8771208b674F27f8EF0Fb \
218
+ --endpoint https://rpc.blaze.soniclabs.com \
219
+ --pyth-contract-address 0x2880aB155794e7179c9eE2e38200202908C17B43 \
220
220
  --price-service-endpoint https://hermes.pyth.network \
221
221
  --mnemonic-file "./mnemonic" \
222
222
  --price-config-file "./price-config.stable.sample.yaml" \
@@ -272,6 +272,8 @@ The following metrics are available:
272
272
  - **pyth_price_last_published_time** (Gauge): The last published time of a price feed in unix timestamp, labeled by price_id and alias
273
273
  - **pyth_price_update_attempts_total** (Counter): Total number of price update attempts with their trigger condition and status, labeled by price_id, alias, trigger, and status
274
274
  - **pyth_price_feeds_total** (Gauge): Total number of price feeds being monitored
275
+ - **pyth_source_price** (Gauge): Latest price value from Pyth source, labeled by price_id and alias
276
+ - **pyth_target_price** (Gauge): Latest price value from target chain, labeled by price_id and alias
275
277
  - **pyth_wallet_balance** (Gauge): Current wallet balance of the price pusher in native token units, labeled by wallet_address and network
276
278
 
277
279
  ### Configuration
@@ -343,6 +345,30 @@ pyth_wallet_balance
343
345
  pyth_wallet_balance < 0.1
344
346
  ```
345
347
 
348
+ 7. Monitor current source price values:
349
+
350
+ ```
351
+ pyth_source_price
352
+ ```
353
+
354
+ 8. Monitor current target price values:
355
+
356
+ ```
357
+ pyth_target_price
358
+ ```
359
+
360
+ 9. Compare source vs target price differences:
361
+
362
+ ```
363
+ abs(pyth_source_price - pyth_target_price) / pyth_source_price * 100
364
+ ```
365
+
366
+ 10. Detect significant price deviations (>1%):
367
+
368
+ ```
369
+ abs(pyth_source_price - pyth_target_price) / pyth_source_price * 100 > 1
370
+ ```
371
+
346
372
  ### Dashboard
347
373
 
348
374
  The docker-compose setup includes a pre-configured Grafana dashboard (`grafana-dashboard.sample.json`) that provides monitoring of your price pusher operations. The dashboard includes the following panels:
@@ -353,6 +379,8 @@ The docker-compose setup includes a pre-configured Grafana dashboard (`grafana-d
353
379
  - **Price Feeds List**: A table listing all configured price feeds with their details.
354
380
  - **Successful Updates (Current Range)**: Graph showing the number of successful price updates over the current range with timeline.
355
381
  - **Update Conditions Distribution**: Pie chart showing the distribution of update conditions (YES/NO/EARLY) over the selected time range.
382
+ - **Source vs Target Price Values**: Graphs showing current price values from both Pyth source and target chains for comparison.
383
+ - **Price Deviation Monitoring**: Panels to track price differences between source and target chains.
356
384
  - **Wallet Balance**: Current balance of your wallet in native token units.
357
385
  - **Wallet Balance Over Time**: Graph tracking your wallet balance over time to monitor consumption.
358
386
  - **Failed Updates (Current Range)**: Graph showing the number of failed price updates over the current range with timeline.
@@ -1,20 +1,35 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AptosPricePusher = exports.APTOS_ACCOUNT_HD_PATH = exports.AptosPriceListener = void 0;
4
- const interface_1 = require("../interface");
5
- const aptos_1 = require("aptos");
6
- class AptosPriceListener extends interface_1.ChainPriceListener {
1
+ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable unicorn/no-await-expression-member */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get APTOS_ACCOUNT_HD_PATH () {
13
+ return APTOS_ACCOUNT_HD_PATH;
14
+ },
15
+ get AptosPriceListener () {
16
+ return AptosPriceListener;
17
+ },
18
+ get AptosPricePusher () {
19
+ return AptosPricePusher;
20
+ }
21
+ });
22
+ const _aptos = require("./aptos.cjs");
23
+ const _interface = require("../interface.cjs");
24
+ class AptosPriceListener extends _interface.ChainPriceListener {
7
25
  pythModule;
8
26
  endpoint;
9
27
  logger;
10
- constructor(pythModule, endpoint, priceItems, logger, config) {
11
- super(config.pollingFrequency, priceItems);
12
- this.pythModule = pythModule;
13
- this.endpoint = endpoint;
14
- this.logger = logger;
28
+ constructor(pythModule, endpoint, priceItems, logger, config){
29
+ super(config.pollingFrequency, priceItems), this.pythModule = pythModule, this.endpoint = endpoint, this.logger = logger;
15
30
  }
16
31
  async getOnChainPriceInfo(priceId) {
17
- const client = new aptos_1.AptosClient(this.endpoint);
32
+ const client = new _aptos.AptosClient(this.endpoint);
18
33
  const res = await client.getAccountResource(this.pythModule, `${this.pythModule}::state::LatestPriceInfo`);
19
34
  try {
20
35
  // This depends upon the pyth contract storage on Aptos and should not be undefined.
@@ -24,37 +39,24 @@ class AptosPriceListener extends interface_1.ChainPriceListener {
24
39
  key_type: `${this.pythModule}::price_identifier::PriceIdentifier`,
25
40
  value_type: `${this.pythModule}::price_info::PriceInfo`,
26
41
  key: {
27
- bytes: priceId,
28
- },
42
+ bytes: priceId
43
+ }
29
44
  });
30
45
  const multiplier = priceItemRes.price_feed.price.price.negative === true ? -1 : 1;
31
46
  const price = multiplier * Number(priceItemRes.price_feed.price.price.magnitude);
32
- this.logger.debug(`Polled an Aptos on-chain price for feed ${this.priceIdToAlias.get(priceId)} (${priceId}).`);
47
+ this.logger.debug(`Polled an Aptos on-chain price for feed ${this.priceIdToAlias.get(priceId) ?? ""} (${priceId}).`);
33
48
  return {
34
49
  price: price.toString(),
35
50
  conf: priceItemRes.price_feed.price.conf,
36
- publishTime: Number(priceItemRes.price_feed.price.timestamp),
51
+ publishTime: Number(priceItemRes.price_feed.price.timestamp)
37
52
  };
38
- }
39
- catch (err) {
40
- this.logger.error(err, `Polling Aptos on-chain price for ${priceId} failed.`);
53
+ } catch (error) {
54
+ this.logger.error(error, `Polling Aptos on-chain price for ${priceId} failed.`);
41
55
  return undefined;
42
56
  }
43
57
  }
44
58
  }
45
- exports.AptosPriceListener = AptosPriceListener;
46
- // Derivation path for aptos accounts
47
- exports.APTOS_ACCOUNT_HD_PATH = "m/44'/637'/0'/0'/0'";
48
- /**
49
- * The `AptosPricePusher` is designed for high-throughput of price updates.
50
- * Achieving this property requires sacrificing some nice-to-have features of other
51
- * pusher implementations that can reduce cost when running multiple pushers. Specifically,
52
- * this implementation does not use `update_price_feeds_if_necssary` and simulate the transaction
53
- * before submission.
54
- *
55
- * If multiple instances of this pusher are running in parallel, both of them will
56
- * land all of their pushed updates on-chain.
57
- */
59
+ const APTOS_ACCOUNT_HD_PATH = "m/44'/637'/0'/0'/0'";
58
60
  class AptosPricePusher {
59
61
  hermesClient;
60
62
  logger;
@@ -66,7 +68,8 @@ class AptosPricePusher {
66
68
  lastSequenceNumber;
67
69
  // If true, we are trying to fetch the most recent sequence number from the blockchain.
68
70
  sequenceNumberLocked;
69
- constructor(hermesClient, logger, pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier) {
71
+ constructor(hermesClient, logger, pythContractAddress, endpoint, mnemonic, // @ts-expect-error - TODO: this class member is unused. remove this exception when it is
72
+ overrideGasPriceMultiplier){
70
73
  this.hermesClient = hermesClient;
71
74
  this.logger = logger;
72
75
  this.pythContractAddress = pythContractAddress;
@@ -76,57 +79,59 @@ class AptosPricePusher {
76
79
  this.sequenceNumberLocked = false;
77
80
  }
78
81
  /**
79
- * Gets price update data which then can be submitted to the Pyth contract to update the prices.
80
- * This will throw an axios error if there is a network problem or the price service returns a non-ok response (e.g: Invalid price ids)
81
- *
82
- * @param priceIds Array of hex-encoded price ids.
83
- * @returns Array of price update data.
84
- */
85
- async getPriceFeedsUpdateData(priceIds) {
82
+ * Gets price update data which then can be submitted to the Pyth contract to update the prices.
83
+ * This will throw an axios error if there is a network problem or the price service returns a non-ok response (e.g: Invalid price ids)
84
+ *
85
+ * @param priceIds - Array of hex-encoded price ids.
86
+ * @returns Array of price update data.
87
+ */ async getPriceFeedsUpdateData(priceIds) {
86
88
  const response = await this.hermesClient.getLatestPriceUpdates(priceIds, {
87
89
  encoding: "base64",
88
- ignoreInvalidPriceIds: true,
90
+ ignoreInvalidPriceIds: true
89
91
  });
90
- return response.binary.data.map((data) => Array.from(Buffer.from(data, "base64")));
92
+ return response.binary.data.map((data)=>[
93
+ ...Buffer.from(data, "base64")
94
+ ]);
91
95
  }
92
96
  async updatePriceFeed(priceIds, pubTimesToPush) {
93
97
  if (priceIds.length === 0) {
94
98
  return;
95
99
  }
96
- if (priceIds.length !== pubTimesToPush.length)
97
- throw new Error("Invalid arguments");
100
+ if (priceIds.length !== pubTimesToPush.length) throw new Error("Invalid arguments");
98
101
  let priceFeedUpdateData;
99
102
  try {
100
103
  // get the latest VAAs for updatePriceFeed and then push them
101
104
  priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds);
102
- }
103
- catch (err) {
104
- this.logger.error(err, "Error fetching the latest vaas to push.");
105
+ } catch (error) {
106
+ this.logger.error(error, "Error fetching the latest vaas to push.");
105
107
  return;
106
108
  }
107
- const account = aptos_1.AptosAccount.fromDerivePath(exports.APTOS_ACCOUNT_HD_PATH, this.mnemonic);
108
- const client = new aptos_1.AptosClient(this.endpoint);
109
+ const account = _aptos.AptosAccount.fromDerivePath(APTOS_ACCOUNT_HD_PATH, this.mnemonic);
110
+ const client = new _aptos.AptosClient(this.endpoint);
109
111
  const sequenceNumber = await this.tryGetNextSequenceNumber(client, account);
110
112
  const rawTx = await client.generateTransaction(account.address(), {
111
113
  function: `${this.pythContractAddress}::pyth::update_price_feeds_with_funder`,
112
114
  type_arguments: [],
113
- arguments: [priceFeedUpdateData],
115
+ arguments: [
116
+ priceFeedUpdateData
117
+ ]
114
118
  }, {
115
- sequence_number: sequenceNumber.toFixed(),
119
+ sequence_number: sequenceNumber.toFixed(0)
116
120
  });
117
121
  try {
118
122
  const signedTx = await client.signTransaction(account, rawTx);
119
123
  const pendingTx = await client.submitTransaction(signedTx);
120
- this.logger.debug({ hash: pendingTx.hash }, "Successfully broadcasted tx.");
124
+ this.logger.debug({
125
+ hash: pendingTx.hash
126
+ }, "Successfully broadcasted tx.");
121
127
  // Sometimes broadcasted txs don't make it on-chain and they cause our sequence number
122
128
  // to go out of sync. Missing transactions are rare and we don't want this check to block
123
129
  // the next price update. So we use spawn a promise without awaiting on it to wait for the
124
130
  // transaction to be confirmed and if it fails, it resets the sequence number and return.
125
- this.waitForTransactionConfirmation(client, pendingTx.hash);
131
+ void this.waitForTransactionConfirmation(client, pendingTx.hash);
126
132
  return;
127
- }
128
- catch (err) {
129
- this.logger.error(err, "Error executing messages");
133
+ } catch (error) {
134
+ this.logger.error(error, "Error executing messages");
130
135
  // Reset the sequence number to re-sync it (in case that was the issue)
131
136
  this.lastSequenceNumber = undefined;
132
137
  return;
@@ -137,12 +142,16 @@ class AptosPricePusher {
137
142
  try {
138
143
  await client.waitForTransaction(txHash, {
139
144
  checkSuccess: true,
140
- timeoutSecs: 10,
145
+ timeoutSecs: 10
141
146
  });
142
- this.logger.info({ hash: txHash }, `Transaction confirmed.`);
143
- }
144
- catch (err) {
145
- this.logger.error({ err, hash: txHash }, `Transaction failed to confirm.`);
147
+ this.logger.info({
148
+ hash: txHash
149
+ }, `Transaction confirmed.`);
150
+ } catch (error) {
151
+ this.logger.error({
152
+ err: error,
153
+ hash: txHash
154
+ }, `Transaction failed to confirm.`);
146
155
  this.lastSequenceNumber = undefined;
147
156
  }
148
157
  }
@@ -150,32 +159,27 @@ class AptosPricePusher {
150
159
  // to predict the next sequence number if possible; if not, it fetches the number from
151
160
  // the blockchain itself (and caches it for later).
152
161
  async tryGetNextSequenceNumber(client, account) {
153
- if (this.lastSequenceNumber !== undefined) {
154
- this.lastSequenceNumber += 1;
155
- return this.lastSequenceNumber;
156
- }
157
- else {
162
+ if (this.lastSequenceNumber === undefined) {
158
163
  // Fetch from the blockchain if we don't have the local cache.
159
164
  // Note that this is locked so that only 1 fetch occurs regardless of how many updates
160
165
  // happen during that fetch.
161
- if (!this.sequenceNumberLocked) {
166
+ if (this.sequenceNumberLocked) {
167
+ throw new Error("Waiting for sequence number in another thread.");
168
+ } else {
162
169
  try {
163
170
  this.sequenceNumberLocked = true;
164
171
  this.lastSequenceNumber = Number((await client.getAccount(account.address())).sequence_number);
165
172
  this.logger.debug(`Fetched account sequence number: ${this.lastSequenceNumber}`);
166
173
  return this.lastSequenceNumber;
167
- }
168
- catch (e) {
169
- throw new Error("Failed to retrieve sequence number" + e);
170
- }
171
- finally {
174
+ } catch (error) {
175
+ throw new Error(`Failed to retrieve sequence number ${error}`);
176
+ } finally{
172
177
  this.sequenceNumberLocked = false;
173
178
  }
174
179
  }
175
- else {
176
- throw new Error("Waiting for sequence number in another thread.");
177
- }
180
+ } else {
181
+ this.lastSequenceNumber += 1;
182
+ return this.lastSequenceNumber;
178
183
  }
179
184
  }
180
185
  }
181
- exports.AptosPricePusher = AptosPricePusher;
@@ -1,7 +1,8 @@
1
- import { ChainPriceListener, IPricePusher, PriceInfo, PriceItem } from "../interface";
2
- import { DurationInSeconds } from "../utils";
3
1
  import { HermesClient } from "@pythnetwork/hermes-client";
4
- import { Logger } from "pino";
2
+ import type { Logger } from "pino";
3
+ import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
4
+ import { ChainPriceListener } from "../interface.js";
5
+ import type { DurationInSeconds } from "../utils.js";
5
6
  export declare class AptosPriceListener extends ChainPriceListener {
6
7
  private pythModule;
7
8
  private endpoint;
@@ -36,7 +37,7 @@ export declare class AptosPricePusher implements IPricePusher {
36
37
  * Gets price update data which then can be submitted to the Pyth contract to update the prices.
37
38
  * This will throw an axios error if there is a network problem or the price service returns a non-ok response (e.g: Invalid price ids)
38
39
  *
39
- * @param priceIds Array of hex-encoded price ids.
40
+ * @param priceIds - Array of hex-encoded price ids.
40
41
  * @returns Array of price update data.
41
42
  */
42
43
  getPriceFeedsUpdateData(priceIds: string[]): Promise<number[][]>;
@@ -44,4 +45,3 @@ export declare class AptosPricePusher implements IPricePusher {
44
45
  private waitForTransactionConfirmation;
45
46
  private tryGetNextSequenceNumber;
46
47
  }
47
- //# sourceMappingURL=aptos.d.ts.map
@@ -1,35 +1,50 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AptosBalanceTracker = void 0;
4
- exports.createAptosBalanceTracker = createAptosBalanceTracker;
5
- const ts_sdk_1 = require("@aptos-labs/ts-sdk");
6
- const interface_1 = require("../interface");
7
- /**
8
- * Aptos-specific implementation of the balance tracker
9
- */
10
- class AptosBalanceTracker extends interface_1.BaseBalanceTracker {
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get AptosBalanceTracker () {
13
+ return AptosBalanceTracker;
14
+ },
15
+ get createAptosBalanceTracker () {
16
+ return createAptosBalanceTracker;
17
+ }
18
+ });
19
+ const _tssdk = require("@aptos-labs/ts-sdk");
20
+ const _interface = require("../interface.cjs");
21
+ class AptosBalanceTracker extends _interface.BaseBalanceTracker {
11
22
  client;
12
23
  aptosAddress;
13
24
  decimals;
14
- constructor(config) {
25
+ constructor(config){
15
26
  super({
16
27
  ...config,
17
- logger: config.logger.child({ module: "AptosBalanceTracker" }),
28
+ logger: config.logger.child({
29
+ module: "AptosBalanceTracker"
30
+ })
18
31
  });
19
- this.client = new ts_sdk_1.Aptos(new ts_sdk_1.AptosConfig({ network: ts_sdk_1.Network.CUSTOM, fullnode: config.endpoint }));
32
+ this.client = new _tssdk.Aptos(new _tssdk.AptosConfig({
33
+ network: _tssdk.Network.CUSTOM,
34
+ fullnode: config.endpoint
35
+ }));
20
36
  this.aptosAddress = config.address;
21
37
  // APT has 8 decimal places by default
22
38
  this.decimals = config.decimals ?? 8;
23
39
  }
24
40
  /**
25
- * Aptos-specific implementation of balance update
26
- * Fetches the native APT balance for the configured address
27
- */
28
- async updateBalance() {
41
+ * Aptos-specific implementation of balance update
42
+ * Fetches the native APT balance for the configured address
43
+ */ async updateBalance() {
29
44
  try {
30
45
  // Get account resource to check the balance
31
46
  const accountAPTAmount = await this.client.getAccountAPTAmount({
32
- accountAddress: this.aptosAddress,
47
+ accountAddress: this.aptosAddress
33
48
  });
34
49
  // Convert the amount to a bigint
35
50
  const balance = BigInt(accountAPTAmount);
@@ -38,16 +53,13 @@ class AptosBalanceTracker extends interface_1.BaseBalanceTracker {
38
53
  // Update metrics with the new balance
39
54
  this.metrics.updateWalletBalance(this.address, this.network, normalizedBalance);
40
55
  this.logger.debug(`Updated Aptos wallet balance: ${this.address} = ${normalizedBalance.toString()} APT (raw: ${balance.toString()})`);
41
- }
42
- catch (error) {
43
- this.logger.error({ error }, "Error fetching Aptos wallet balance for metrics");
56
+ } catch (error) {
57
+ this.logger.error({
58
+ error
59
+ }, "Error fetching Aptos wallet balance for metrics");
44
60
  }
45
61
  }
46
62
  }
47
- exports.AptosBalanceTracker = AptosBalanceTracker;
48
- /**
49
- * Factory function to create a balance tracker for Aptos chain
50
- */
51
63
  function createAptosBalanceTracker(params) {
52
64
  return new AptosBalanceTracker({
53
65
  endpoint: params.endpoint,
@@ -56,6 +68,6 @@ function createAptosBalanceTracker(params) {
56
68
  updateInterval: params.updateInterval,
57
69
  metrics: params.metrics,
58
70
  logger: params.logger,
59
- decimals: params.decimals,
71
+ decimals: params.decimals
60
72
  });
61
73
  }
@@ -1,18 +1,19 @@
1
- import { BaseBalanceTracker, BaseBalanceTrackerConfig, IBalanceTracker } from "../interface";
2
- import { DurationInSeconds } from "../utils";
3
- import { PricePusherMetrics } from "../metrics";
4
- import { Logger } from "pino";
1
+ import type { Logger } from "pino";
2
+ import type { BaseBalanceTrackerConfig, IBalanceTracker } from "../interface.js";
3
+ import { BaseBalanceTracker } from "../interface.js";
4
+ import { PricePusherMetrics } from "../metrics.js";
5
+ import type { DurationInSeconds } from "../utils.js";
5
6
  /**
6
7
  * Aptos-specific configuration for balance tracker
7
8
  */
8
- export interface AptosBalanceTrackerConfig extends BaseBalanceTrackerConfig {
9
+ export type AptosBalanceTrackerConfig = {
9
10
  /** Aptos node endpoint URL */
10
11
  endpoint: string;
11
12
  /** Aptos account address */
12
13
  address: string;
13
14
  /** Optional decimal places for APT token (default: 8) */
14
15
  decimals?: number;
15
- }
16
+ } & BaseBalanceTrackerConfig;
16
17
  /**
17
18
  * Aptos-specific implementation of the balance tracker
18
19
  */
@@ -30,7 +31,7 @@ export declare class AptosBalanceTracker extends BaseBalanceTracker {
30
31
  /**
31
32
  * Parameters for creating an Aptos balance tracker
32
33
  */
33
- export interface CreateAptosBalanceTrackerParams {
34
+ export type CreateAptosBalanceTrackerParams = {
34
35
  endpoint: string;
35
36
  address: string;
36
37
  network: string;
@@ -38,9 +39,8 @@ export interface CreateAptosBalanceTrackerParams {
38
39
  metrics: PricePusherMetrics;
39
40
  logger: Logger;
40
41
  decimals?: number;
41
- }
42
+ };
42
43
  /**
43
44
  * Factory function to create a balance tracker for Aptos chain
44
45
  */
45
46
  export declare function createAptosBalanceTracker(params: CreateAptosBalanceTrackerParams): IBalanceTracker;
46
- //# sourceMappingURL=balance-tracker.d.ts.map
@@ -0,0 +1,161 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-explicit-any */ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return _default;
9
+ }
10
+ });
11
+ const _nodefs = /*#__PURE__*/ _interop_require_default(require("node:fs"));
12
+ const _hermesclient = require("@pythnetwork/hermes-client");
13
+ const _aptos = require("./aptos.cjs");
14
+ const _pino = /*#__PURE__*/ _interop_require_default(require("pino"));
15
+ const _controller = require("../controller.cjs");
16
+ const _metrics = require("../metrics.cjs");
17
+ const _options = /*#__PURE__*/ _interop_require_wildcard(require("../options.cjs"));
18
+ const _priceconfig = require("../price-config.cjs");
19
+ const _pythpricelistener = require("../pyth-price-listener.cjs");
20
+ const _aptos1 = require("./aptos.cjs");
21
+ const _utils = require("../utils.cjs");
22
+ const _balancetracker = require("./balance-tracker.cjs");
23
+ function _interop_require_default(obj) {
24
+ return obj && obj.__esModule ? obj : {
25
+ default: obj
26
+ };
27
+ }
28
+ function _getRequireWildcardCache(nodeInterop) {
29
+ if (typeof WeakMap !== "function") return null;
30
+ var cacheBabelInterop = new WeakMap();
31
+ var cacheNodeInterop = new WeakMap();
32
+ return (_getRequireWildcardCache = function(nodeInterop) {
33
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
34
+ })(nodeInterop);
35
+ }
36
+ function _interop_require_wildcard(obj, nodeInterop) {
37
+ if (!nodeInterop && obj && obj.__esModule) {
38
+ return obj;
39
+ }
40
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
41
+ return {
42
+ default: obj
43
+ };
44
+ }
45
+ var cache = _getRequireWildcardCache(nodeInterop);
46
+ if (cache && cache.has(obj)) {
47
+ return cache.get(obj);
48
+ }
49
+ var newObj = {
50
+ __proto__: null
51
+ };
52
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
53
+ for(var key in obj){
54
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
55
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
56
+ if (desc && (desc.get || desc.set)) {
57
+ Object.defineProperty(newObj, key, desc);
58
+ } else {
59
+ newObj[key] = obj[key];
60
+ }
61
+ }
62
+ }
63
+ newObj.default = obj;
64
+ if (cache) {
65
+ cache.set(obj, newObj);
66
+ }
67
+ return newObj;
68
+ }
69
+ const _default = {
70
+ command: "aptos",
71
+ describe: "run price pusher for aptos",
72
+ builder: {
73
+ endpoint: {
74
+ description: "RPC endpoint endpoint URL for aptos. The pusher will periodically" + "poll for updates. The polling interval is configurable via the " + "`polling-frequency` command-line argument.",
75
+ type: "string",
76
+ required: true
77
+ },
78
+ "override-gas-price-multiplier": {
79
+ description: "Multiply the gas price by this number if the transaction is not landing to override it. Default 2",
80
+ type: "number",
81
+ required: false,
82
+ default: 2
83
+ },
84
+ ..._options.priceConfigFile,
85
+ ..._options.priceServiceEndpoint,
86
+ ..._options.mnemonicFile,
87
+ ..._options.pythContractAddress,
88
+ ..._options.pollingFrequency,
89
+ ..._options.pushingFrequency,
90
+ ..._options.logLevel,
91
+ ..._options.controllerLogLevel,
92
+ ..._options.enableMetrics,
93
+ ..._options.metricsPort
94
+ },
95
+ handler: async function(argv) {
96
+ // FIXME: type checks for this
97
+ const { endpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, overrideGasPriceMultiplier, logLevel, controllerLogLevel, enableMetrics, metricsPort } = argv;
98
+ const logger = (0, _pino.default)({
99
+ level: logLevel
100
+ });
101
+ const priceConfigs = (0, _priceconfig.readPriceConfigFile)(priceConfigFile);
102
+ const hermesClient = new _hermesclient.HermesClient(priceServiceEndpoint);
103
+ // Initialize metrics if enabled
104
+ let metrics;
105
+ if (enableMetrics) {
106
+ metrics = new _metrics.PricePusherMetrics(logger.child({
107
+ module: "Metrics"
108
+ }));
109
+ metrics.start(metricsPort);
110
+ logger.info(`Metrics server started on port ${metricsPort}`);
111
+ }
112
+ const mnemonic = _nodefs.default.readFileSync(mnemonicFile, "utf8").trim();
113
+ const account = _aptos.AptosAccount.fromDerivePath(_aptos1.APTOS_ACCOUNT_HD_PATH, mnemonic);
114
+ logger.info(`Pushing from account address: ${account.address()}`);
115
+ let priceItems = priceConfigs.map(({ id, alias })=>({
116
+ id,
117
+ alias
118
+ }));
119
+ // Better to filter out invalid price items before creating the pyth listener
120
+ const { existingPriceItems, invalidPriceItems } = await (0, _utils.filterInvalidPriceItems)(hermesClient, priceItems);
121
+ if (invalidPriceItems.length > 0) {
122
+ logger.error(`Invalid price id submitted for: ${invalidPriceItems.map(({ alias })=>alias).join(", ")}`);
123
+ }
124
+ priceItems = existingPriceItems;
125
+ const pythListener = new _pythpricelistener.PythPriceListener(hermesClient, priceItems, logger.child({
126
+ module: "PythPriceListener"
127
+ }));
128
+ const aptosListener = new _aptos1.AptosPriceListener(pythContractAddress, endpoint, priceItems, logger.child({
129
+ module: "AptosPriceListener"
130
+ }), {
131
+ pollingFrequency
132
+ });
133
+ const aptosPusher = new _aptos1.AptosPricePusher(hermesClient, logger.child({
134
+ module: "AptosPricePusher"
135
+ }), pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier);
136
+ const controller = new _controller.Controller(priceConfigs, pythListener, aptosListener, aptosPusher, logger.child({
137
+ module: "Controller"
138
+ }, {
139
+ level: controllerLogLevel
140
+ }), {
141
+ pushingFrequency,
142
+ metrics: metrics
143
+ });
144
+ // Create and start the balance tracker if metrics are enabled
145
+ if (metrics) {
146
+ const balanceTracker = (0, _balancetracker.createAptosBalanceTracker)({
147
+ address: account.address().toString(),
148
+ endpoint,
149
+ network: "aptos",
150
+ updateInterval: pushingFrequency,
151
+ metrics,
152
+ logger: logger.child({
153
+ module: "AptosBalanceTracker"
154
+ })
155
+ });
156
+ // Start the balance tracker
157
+ await balanceTracker.start();
158
+ }
159
+ void controller.start();
160
+ }
161
+ };
@@ -1,4 +1,4 @@
1
- import { Options } from "yargs";
1
+ import type { Options } from "yargs";
2
2
  declare const _default: {
3
3
  command: string;
4
4
  describe: string;
@@ -19,4 +19,3 @@ declare const _default: {
19
19
  handler: (argv: any) => Promise<void>;
20
20
  };
21
21
  export default _default;
22
- //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
@@ -2,4 +2,3 @@ export type PushAttempt = {
2
2
  nonce: number;
3
3
  gasPrice: number;
4
4
  };
5
- //# sourceMappingURL=common.d.ts.map