@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/lib/evm/evm.js DELETED
@@ -1,270 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EvmPricePusher = exports.EvmPriceListener = void 0;
4
- const interface_1 = require("../interface");
5
- const utils_1 = require("../utils");
6
- const viem_1 = require("viem");
7
- class EvmPriceListener extends interface_1.ChainPriceListener {
8
- pythContract;
9
- watchEvents;
10
- logger;
11
- constructor(pythContract, priceItems, watchEvents, logger, config) {
12
- super(config.pollingFrequency, priceItems);
13
- this.pythContract = pythContract;
14
- this.watchEvents = watchEvents;
15
- this.logger = logger;
16
- this.pythContract = pythContract;
17
- this.logger = logger;
18
- }
19
- // This method should be awaited on and once it finishes it has the latest value
20
- // for the given price feeds (if they exist).
21
- async start() {
22
- if (this.watchEvents) {
23
- this.logger.info("Watching target network pyth contract events...");
24
- this.startWatching();
25
- }
26
- else {
27
- this.logger.info("The target network RPC endpoint is not Websocket. " +
28
- "Listening for updates only via polling....");
29
- }
30
- // base class for polling
31
- await super.start();
32
- }
33
- async startWatching() {
34
- this.pythContract.watchEvent.PriceFeedUpdate({ id: this.priceItems.map((item) => (0, utils_1.addLeading0x)(item.id)) }, { strict: true, onLogs: this.onPriceFeedUpdate.bind(this) });
35
- }
36
- onPriceFeedUpdate(logs) {
37
- for (const log of logs) {
38
- const priceId = (0, utils_1.removeLeading0x)((0, utils_1.assertDefined)(log.args.id));
39
- const priceInfo = {
40
- conf: (0, utils_1.assertDefined)(log.args.conf).toString(),
41
- price: (0, utils_1.assertDefined)(log.args.price).toString(),
42
- publishTime: Number((0, utils_1.assertDefined)(log.args.publishTime)),
43
- };
44
- this.logger.debug({ priceInfo }, `Received a new Evm PriceFeedUpdate event for price feed ${this.priceIdToAlias.get(priceId)} (${priceId}).`);
45
- this.updateLatestPriceInfo(priceId, priceInfo);
46
- }
47
- }
48
- async getOnChainPriceInfo(priceId) {
49
- let priceRaw;
50
- try {
51
- priceRaw = await this.pythContract.read.getPriceUnsafe([
52
- (0, utils_1.addLeading0x)(priceId),
53
- ]);
54
- }
55
- catch (err) {
56
- this.logger.error(err, `Polling on-chain price for ${priceId} failed.`);
57
- return undefined;
58
- }
59
- this.logger.debug(`Polled an EVM on chain price for feed ${this.priceIdToAlias.get(priceId)} (${priceId}).`);
60
- return {
61
- conf: priceRaw.conf,
62
- price: priceRaw.price,
63
- publishTime: Number(priceRaw.publishTime),
64
- };
65
- }
66
- }
67
- exports.EvmPriceListener = EvmPriceListener;
68
- class EvmPricePusher {
69
- hermesClient;
70
- client;
71
- pythContract;
72
- logger;
73
- overrideGasPriceMultiplier;
74
- overrideGasPriceMultiplierCap;
75
- updateFeeMultiplier;
76
- gasLimit;
77
- customGasStation;
78
- gasPrice;
79
- pusherAddress;
80
- lastPushAttempt;
81
- constructor(hermesClient, client, pythContract, logger, overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, updateFeeMultiplier, gasLimit, customGasStation, gasPrice) {
82
- this.hermesClient = hermesClient;
83
- this.client = client;
84
- this.pythContract = pythContract;
85
- this.logger = logger;
86
- this.overrideGasPriceMultiplier = overrideGasPriceMultiplier;
87
- this.overrideGasPriceMultiplierCap = overrideGasPriceMultiplierCap;
88
- this.updateFeeMultiplier = updateFeeMultiplier;
89
- this.gasLimit = gasLimit;
90
- this.customGasStation = customGasStation;
91
- this.gasPrice = gasPrice;
92
- }
93
- // The pubTimes are passed here to use the values that triggered the push.
94
- // This is an optimization to avoid getting a newer value (as an update comes)
95
- // and will help multiple price pushers to have consistent behaviour.
96
- // To ensure that we transactions are landing and we are not pushing the prices twice
97
- // we will re-use the same nonce (with a higher gas price) if the previous transaction
98
- // is not landed yet.
99
- async updatePriceFeed(priceIds, pubTimesToPush) {
100
- if (priceIds.length === 0) {
101
- return;
102
- }
103
- if (priceIds.length !== pubTimesToPush.length)
104
- throw new Error("Invalid arguments");
105
- const priceFeedUpdateData = (await this.getPriceFeedsUpdateData(priceIds));
106
- const priceFeedUpdateDataWith0x = priceFeedUpdateData.map((data) => (0, utils_1.addLeading0x)(data));
107
- let updateFee;
108
- try {
109
- updateFee = await this.pythContract.read.getUpdateFee([
110
- priceFeedUpdateDataWith0x,
111
- ]);
112
- updateFee = BigInt(Math.round(Number(updateFee) * (this.updateFeeMultiplier || 1)));
113
- this.logger.debug(`Update fee: ${updateFee}`);
114
- }
115
- catch (e) {
116
- this.logger.error(e, "An unidentified error has occured when getting the update fee.");
117
- throw e;
118
- }
119
- // Gas price in networks with transaction type eip1559 represents the
120
- // addition of baseFee and priorityFee required to land the transaction. We
121
- // are using this to remain compatible with the networks that doesn't
122
- // support this transaction type.
123
- let gasPrice = this.gasPrice ??
124
- Number(await (this.customGasStation?.getCustomGasPrice() ??
125
- this.client.getGasPrice()));
126
- // Try to re-use the same nonce and increase the gas if the last tx is not landed yet.
127
- if (this.pusherAddress === undefined) {
128
- this.pusherAddress = this.client.account.address;
129
- }
130
- const lastExecutedNonce = (await this.client.getTransactionCount({
131
- address: this.pusherAddress,
132
- })) - 1;
133
- let gasPriceToOverride = undefined;
134
- if (this.lastPushAttempt !== undefined) {
135
- if (this.lastPushAttempt.nonce <= lastExecutedNonce) {
136
- this.lastPushAttempt = undefined;
137
- }
138
- else {
139
- gasPriceToOverride =
140
- this.lastPushAttempt.gasPrice * this.overrideGasPriceMultiplier;
141
- }
142
- }
143
- if (gasPriceToOverride !== undefined &&
144
- gasPriceToOverride > Number(gasPrice)) {
145
- gasPrice = Math.min(gasPriceToOverride, gasPrice * this.overrideGasPriceMultiplierCap);
146
- }
147
- const txNonce = lastExecutedNonce + 1;
148
- this.logger.debug(`Using gas price: ${gasPrice} and nonce: ${txNonce}`);
149
- const pubTimesToPushParam = pubTimesToPush.map((pubTime) => BigInt(pubTime));
150
- const priceIdsWith0x = priceIds.map((priceId) => (0, utils_1.addLeading0x)(priceId));
151
- // Update lastAttempt
152
- this.lastPushAttempt = {
153
- nonce: txNonce,
154
- gasPrice: gasPrice,
155
- };
156
- try {
157
- const { request } = await this.pythContract.simulate.updatePriceFeedsIfNecessary([priceFeedUpdateDataWith0x, priceIdsWith0x, pubTimesToPushParam], {
158
- value: updateFee,
159
- gasPrice: BigInt(Math.ceil(gasPrice)),
160
- nonce: txNonce,
161
- gas: this.gasLimit !== undefined
162
- ? BigInt(Math.ceil(this.gasLimit))
163
- : undefined,
164
- });
165
- this.logger.debug({ request }, "Simulated request successfully");
166
- const hash = await this.client.writeContract(request);
167
- this.logger.info({ hash }, "Price update sent");
168
- this.waitForTransactionReceipt(hash);
169
- }
170
- catch (err) {
171
- this.logger.debug({ err }, "Simulating or sending transactions failed.");
172
- if (err instanceof viem_1.BaseError) {
173
- if (err.walk((e) => e instanceof viem_1.ContractFunctionRevertedError &&
174
- e.data?.errorName === "NoFreshUpdate")) {
175
- this.logger.info("Simulation reverted because none of the updates are fresh. This is an expected behaviour to save gas. Skipping this push.");
176
- return;
177
- }
178
- if (err.walk((e) => e instanceof viem_1.InsufficientFundsError)) {
179
- this.logger.error({ err }, "Wallet doesn't have enough balance. In rare cases, there might be issues with gas price " +
180
- "calculation in the RPC.");
181
- throw err;
182
- }
183
- if (err.walk((e) => e instanceof viem_1.FeeCapTooLowError) ||
184
- err.walk((e) => e instanceof viem_1.InternalRpcError &&
185
- e.details.includes("replacement transaction underpriced"))) {
186
- this.logger.warn("The gas price of the transaction is too low or there is an existing transaction with higher gas with the same nonce. " +
187
- "The price will be increased in the next push. Skipping this push. " +
188
- "If this keeps happening or transactions are not landing you need to increase the override gas price " +
189
- "multiplier and the cap to increase the likelihood of the transaction landing on-chain.");
190
- return;
191
- }
192
- if (err.walk((e) => e instanceof viem_1.TransactionExecutionError &&
193
- (e.details.includes("nonce too low") ||
194
- e.message.includes("Nonce provided for the transaction")))) {
195
- this.logger.info("The nonce is incorrect. This is an expected behaviour in high frequency or multi-instance setup. Skipping this push.");
196
- return;
197
- }
198
- // Sometimes the contract function execution fails in simulation and this error is thrown.
199
- if (err.walk((e) => e instanceof viem_1.ContractFunctionExecutionError)) {
200
- this.logger.warn({ err }, "The contract function execution failed in simulation. This is an expected behaviour in high frequency or multi-instance setup. " +
201
- "Please review this error and file an issue if it is a bug. Skipping this push.");
202
- return;
203
- }
204
- // We normally crash on unknown failures but we believe that this type of error is safe to skip. The other reason is that
205
- // wometimes we see a TransactionExecutionError because of the nonce without any details and it is not catchable.
206
- if (err.walk((e) => e instanceof viem_1.TransactionExecutionError)) {
207
- this.logger.error({ err }, "Transaction execution failed. This is an expected behaviour in high frequency or multi-instance setup. " +
208
- "Please review this error and file an issue if it is a bug. Skipping this push.");
209
- return;
210
- }
211
- // The following errors are part of the legacy code and might not work as expected.
212
- // We are keeping them in case they help with handling what is not covered above.
213
- if (err.message.includes("the tx doesn't have the correct nonce.") ||
214
- err.message.includes("nonce too low") ||
215
- err.message.includes("invalid nonce")) {
216
- this.logger.info("The nonce is incorrect (are multiple users using this account?). Skipping this push.");
217
- return;
218
- }
219
- if (err.message.includes("max fee per gas less than block base fee")) {
220
- // We just have to handle this error and return.
221
- // LastPushAttempt was stored with the class
222
- // Next time the update will be executing, it will check the last attempt
223
- // and increase the gas price accordingly.
224
- this.logger.warn("The transaction failed with error: max fee per gas less than block base fee. " +
225
- "The fee will be increased in the next push. Skipping this push.");
226
- return;
227
- }
228
- if (err.message.includes("sender doesn't have enough funds to send tx.")) {
229
- this.logger.error("Payer is out of balance, please top it up.");
230
- throw new Error("Please top up the wallet");
231
- }
232
- if (err.message.includes("could not replace existing tx")) {
233
- this.logger.error("A transaction with the same nonce has been mined and this one is no longer needed. Skipping this push.");
234
- return;
235
- }
236
- }
237
- // If the error is not handled, we will crash the process.
238
- this.logger.error({ err }, "The transaction failed with an unhandled error. crashing the process. " +
239
- "Please review this error and file an issue if it is a bug.");
240
- throw err;
241
- }
242
- }
243
- async waitForTransactionReceipt(hash) {
244
- try {
245
- const receipt = await this.client.waitForTransactionReceipt({
246
- hash: hash,
247
- });
248
- switch (receipt.status) {
249
- case "success":
250
- this.logger.debug({ hash, receipt }, "Price update successful");
251
- this.logger.info({ hash }, "Price update successful");
252
- break;
253
- default:
254
- this.logger.info({ hash, receipt }, "Price update did not succeed or its transaction did not land. " +
255
- "This is an expected behaviour in high frequency or multi-instance setup.");
256
- }
257
- }
258
- catch (err) {
259
- this.logger.warn({ err }, "Failed to get transaction receipt");
260
- }
261
- }
262
- async getPriceFeedsUpdateData(priceIds) {
263
- const response = await this.hermesClient.getLatestPriceUpdates(priceIds, {
264
- encoding: "hex",
265
- ignoreInvalidPriceIds: true,
266
- });
267
- return response.binary.data;
268
- }
269
- }
270
- exports.EvmPricePusher = EvmPricePusher;
@@ -1 +0,0 @@
1
- {"version":3,"file":"pyth-abi.d.ts","sourceRoot":"","sources":["../../src/evm/pyth-abi.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkiBX,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;EAgCjB,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuEhB,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIV,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pyth-contract.d.ts","sourceRoot":"","sources":["../../src/evm/pyth-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,OAAO,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,YAAY,GAAG,qBAAqB,CAC9C,OAAO,OAAO,EACd,iBAAiB,CAClB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,iBAAiB,EACzB,SAAS,OAAO,KACf,YAKC,CAAC"}
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createPythContract = void 0;
4
- const viem_1 = require("viem");
5
- const pyth_abi_1 = require("./pyth-abi");
6
- const createPythContract = (client, address) => (0, viem_1.getContract)({
7
- client,
8
- abi: pyth_abi_1.PythAbi,
9
- address,
10
- });
11
- exports.createPythContract = createPythContract;
@@ -1 +0,0 @@
1
- {"version":3,"file":"super-wallet.d.ts","sourceRoot":"","sources":["../../src/evm/super-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,OAAO,EACP,KAAK,EAEL,MAAM,EACN,SAAS,EACT,aAAa,EACb,aAAa,EAGb,SAAS,EACV,MAAM,MAAM,CAAC;AAmBd,MAAM,MAAM,iBAAiB,GAAG,MAAM,CACpC,SAAS,EACT,KAAK,EACL,OAAO,EACP,SAAS,EACT,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CACzE,CAAC;AAcF,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,OAAO,CAAC,iBAAiB,CAY3B,CAAC"}
@@ -1,73 +0,0 @@
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 () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.createClient = void 0;
37
- const viem_1 = require("viem");
38
- const accounts_1 = require("viem/accounts");
39
- const chains = __importStar(require("viem/chains"));
40
- const utils_1 = require("../utils");
41
- const UNKNOWN_CHAIN_CONFIG = {
42
- name: "Unknown",
43
- nativeCurrency: {
44
- name: "Unknown",
45
- symbol: "Unknown",
46
- decimals: 18,
47
- },
48
- rpcUrls: {
49
- default: {
50
- http: [],
51
- },
52
- },
53
- };
54
- // Get the transport based on the endpoint
55
- const getTransport = (endpoint) => (0, utils_1.isWsEndpoint)(endpoint) ? (0, viem_1.webSocket)(endpoint) : (0, viem_1.http)(endpoint);
56
- // Get the chain corresponding to the chainId. If the chain is not found, it will return
57
- // an unknown chain which should work fine in most of the cases. We might need to update
58
- // the viem package to support new chains if they don't work as expected with the unknown
59
- // chain.
60
- const getChainById = (chainId) => Object.values(chains).find((chain) => chain.id === chainId) ||
61
- (0, viem_1.defineChain)({ id: chainId, ...UNKNOWN_CHAIN_CONFIG });
62
- const createClient = async (endpoint, mnemonic) => {
63
- const transport = getTransport(endpoint);
64
- const chainId = await (0, viem_1.createPublicClient)({
65
- transport,
66
- }).getChainId();
67
- return (0, viem_1.createWalletClient)({
68
- transport,
69
- account: (0, accounts_1.mnemonicToAccount)(mnemonic),
70
- chain: getChainById(chainId),
71
- }).extend(viem_1.publicActions);
72
- };
73
- exports.createClient = createClient;
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/fuel/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;kBAmBvB,OAAO;4BAKP,OAAO;iCAKP,OAAO;;oBAQiB,GAAG;;AA1BpC,wBAiGE"}
@@ -1,98 +0,0 @@
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 () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const options = __importStar(require("../options"));
40
- const price_config_1 = require("../price-config");
41
- const hermes_client_1 = require("@pythnetwork/hermes-client");
42
- const pyth_price_listener_1 = require("../pyth-price-listener");
43
- const fuel_1 = require("./fuel");
44
- const controller_1 = require("../controller");
45
- const fuels_1 = require("fuels");
46
- const fs_1 = __importDefault(require("fs"));
47
- const pino_1 = __importDefault(require("pino"));
48
- const utils_1 = require("../utils");
49
- exports.default = {
50
- command: "fuel",
51
- describe: "run price pusher for Fuel",
52
- builder: {
53
- endpoint: {
54
- description: "Fuel RPC API endpoint",
55
- type: "string",
56
- required: true,
57
- },
58
- "private-key-file": {
59
- description: "Path to the private key file",
60
- type: "string",
61
- required: true,
62
- },
63
- "pyth-contract-address": {
64
- description: "Pyth contract address on Fuel",
65
- type: "string",
66
- required: true,
67
- },
68
- ...options.priceConfigFile,
69
- ...options.priceServiceEndpoint,
70
- ...options.pushingFrequency,
71
- ...options.pollingFrequency,
72
- ...options.logLevel,
73
- ...options.controllerLogLevel,
74
- },
75
- handler: async function (argv) {
76
- const { endpoint, privateKeyFile, pythContractAddress, priceConfigFile, priceServiceEndpoint, pushingFrequency, pollingFrequency, logLevel, controllerLogLevel, } = argv;
77
- const logger = (0, pino_1.default)({ level: logLevel });
78
- const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
79
- const hermesClient = new hermes_client_1.HermesClient(priceServiceEndpoint);
80
- let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
81
- // Better to filter out invalid price items before creating the pyth listener
82
- const { existingPriceItems, invalidPriceItems } = await (0, utils_1.filterInvalidPriceItems)(hermesClient, priceItems);
83
- if (invalidPriceItems.length > 0) {
84
- logger.error(`Invalid price id submitted for: ${invalidPriceItems
85
- .map(({ alias }) => alias)
86
- .join(", ")}`);
87
- }
88
- priceItems = existingPriceItems;
89
- const pythListener = new pyth_price_listener_1.PythPriceListener(hermesClient, priceItems, logger.child({ module: "PythPriceListener" }));
90
- const provider = await fuels_1.Provider.create(endpoint);
91
- const privateKey = fs_1.default.readFileSync(privateKeyFile, "utf8").trim();
92
- const wallet = fuels_1.Wallet.fromPrivateKey(privateKey, provider);
93
- const fuelPriceListener = new fuel_1.FuelPriceListener(provider, pythContractAddress, priceItems, logger.child({ module: "FuelPriceListener" }), { pollingFrequency });
94
- const fuelPricePusher = new fuel_1.FuelPricePusher(wallet, pythContractAddress, hermesClient, logger.child({ module: "FuelPricePusher" }));
95
- const controller = new controller_1.Controller(priceConfigs, pythListener, fuelPriceListener, fuelPricePusher, logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency });
96
- await controller.start();
97
- },
98
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"fuel.d.ts","sourceRoot":"","sources":["../../src/fuel/fuel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAgB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAA+B,MAAM,EAAM,MAAM,OAAO,CAAC;AAc1E,qBAAa,iBAAkB,SAAQ,kBAAkB;IAIrD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,cAAc;IAEtB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAAW;gBAGjB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,EAC9B,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6B3E;AAED,qBAAa,eAAgB,YAAW,YAAY;IAIhD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAAW;gBAGjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM;IASlB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAElB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;CAuCjB"}
package/lib/fuel/fuel.js DELETED
@@ -1,101 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FuelPricePusher = exports.FuelPriceListener = void 0;
4
- const interface_1 = require("../interface");
5
- const utils_1 = require("../utils");
6
- const fuels_1 = require("fuels");
7
- const pyth_fuel_js_1 = require("@pythnetwork/pyth-fuel-js");
8
- // Convert TAI64 timestamp to Unix timestamp
9
- function tai64ToUnix(tai64) {
10
- // TAI64 is 2^62 seconds ahead of Unix epoch (1970-01-01)
11
- // Additional 10-second offset accounts for TAI being ahead of UTC at Unix epoch
12
- const result = BigInt(tai64.toString()) - BigInt(2n ** 62n) - 10n;
13
- return Number(result);
14
- }
15
- class FuelPriceListener extends interface_1.ChainPriceListener {
16
- provider;
17
- pythContractId;
18
- logger;
19
- contract;
20
- constructor(provider, pythContractId, priceItems, logger, config) {
21
- super(config.pollingFrequency, priceItems);
22
- this.provider = provider;
23
- this.pythContractId = pythContractId;
24
- this.logger = logger;
25
- this.contract = new fuels_1.Contract(this.pythContractId, pyth_fuel_js_1.PYTH_CONTRACT_ABI, this.provider);
26
- }
27
- async getOnChainPriceInfo(priceId) {
28
- try {
29
- const formattedPriceId = (0, utils_1.addLeading0x)(priceId);
30
- const priceInfo = await this.contract.functions
31
- .price_unsafe(formattedPriceId)
32
- .get();
33
- console.log({
34
- conf: priceInfo.value.confidence.toString(),
35
- price: priceInfo.value.price.toString(),
36
- publishTime: tai64ToUnix(priceInfo.value.publish_time),
37
- });
38
- this.logger.debug(`Polled a Fuel on chain price for feed ${this.priceIdToAlias.get(priceId)} (${priceId}).`);
39
- return {
40
- conf: priceInfo.value.confidence.toString(),
41
- price: priceInfo.value.price.toString(),
42
- publishTime: tai64ToUnix(priceInfo.value.publish_time),
43
- };
44
- }
45
- catch (err) {
46
- this.logger.error({ err, priceId }, `Polling on-chain price failed.`);
47
- return undefined;
48
- }
49
- }
50
- }
51
- exports.FuelPriceListener = FuelPriceListener;
52
- class FuelPricePusher {
53
- wallet;
54
- pythContractId;
55
- hermesClient;
56
- logger;
57
- contract;
58
- constructor(wallet, pythContractId, hermesClient, logger) {
59
- this.wallet = wallet;
60
- this.pythContractId = pythContractId;
61
- this.hermesClient = hermesClient;
62
- this.logger = logger;
63
- this.contract = new fuels_1.Contract(this.pythContractId, pyth_fuel_js_1.PYTH_CONTRACT_ABI, this.wallet);
64
- }
65
- async updatePriceFeed(priceIds,
66
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
- pubTimesToPush) {
68
- if (priceIds.length === 0) {
69
- return;
70
- }
71
- let priceFeedUpdateData;
72
- try {
73
- const response = await this.hermesClient.getLatestPriceUpdates(priceIds, {
74
- encoding: "base64",
75
- ignoreInvalidPriceIds: true,
76
- });
77
- priceFeedUpdateData = response.binary.data;
78
- }
79
- catch (err) {
80
- this.logger.error(err, "getPriceFeedsUpdateData failed");
81
- return;
82
- }
83
- const updateData = priceFeedUpdateData.map((data) => (0, fuels_1.arrayify)(data));
84
- try {
85
- const updateFee = await this.contract.functions
86
- .update_fee(updateData)
87
- .get();
88
- const result = await this.contract.functions
89
- .update_price_feeds(updateData)
90
- .callParams({
91
- forward: [updateFee.value, (0, fuels_1.hexlify)(pyth_fuel_js_1.FUEL_ETH_ASSET_ID)],
92
- })
93
- .call();
94
- this.logger.info({ transactionId: result.transactionId }, "updatePriceFeed successful");
95
- }
96
- catch (err) {
97
- this.logger.error(err, "updatePriceFeed failed");
98
- }
99
- }
100
- }
101
- exports.FuelPricePusher = FuelPricePusher;
package/lib/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/lib/index.js DELETED
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const yargs_1 = __importDefault(require("yargs"));
8
- const helpers_1 = require("yargs/helpers");
9
- const command_1 = __importDefault(require("./injective/command"));
10
- const command_2 = __importDefault(require("./evm/command"));
11
- const command_3 = __importDefault(require("./aptos/command"));
12
- const command_4 = __importDefault(require("./sui/command"));
13
- const command_5 = __importDefault(require("./near/command"));
14
- const command_6 = __importDefault(require("./solana/command"));
15
- const command_7 = __importDefault(require("./fuel/command"));
16
- const command_8 = __importDefault(require("./ton/command"));
17
- const options_1 = require("./options");
18
- (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
19
- .parserConfiguration({
20
- "parse-numbers": false,
21
- })
22
- .config("config")
23
- .global("config")
24
- .option("enable-metrics", options_1.enableMetrics["enable-metrics"])
25
- .option("metrics-port", options_1.metricsPort["metrics-port"])
26
- .command(command_2.default)
27
- .command(command_7.default)
28
- .command(command_1.default)
29
- .command(command_3.default)
30
- .command(command_4.default)
31
- .command(command_5.default)
32
- .command(command_6.default)
33
- .command(command_8.default)
34
- .help().argv;
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/injective/command.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;yBAevB,OAAO;iBAKP,OAAO;qBAIP,OAAO;0BAIP,OAAO;wCAMP,OAAO;;oBAUiB,GAAG;;AAxCpC,wBA4HE"}