@pythnetwork/price-pusher 5.7.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,7 @@ The parameters above are configured per price feed in a price configuration YAML
37
37
  time_difference: 60 # Time difference threshold (in seconds) to push a newer price feed.
38
38
  price_deviation: 0.5 # The price deviation (%) threshold to push a newer price feed.
39
39
  confidence_ratio: 1 # The confidence/price (%) threshold to push a newer price feed.
40
+
40
41
  # Optional block to configure whether this feed can be early updated. If at least one feed meets the
41
42
  # triggering conditions above, all other feeds who meet the early update conditions will be included in
42
43
  # the submitted batch of prices. This logic takes advantage of the fact that adding a feed to a larger
@@ -49,11 +50,35 @@ The parameters above are configured per price feed in a price configuration YAML
49
50
  - ...
50
51
  ```
51
52
 
53
+ By default, the price pusher will automatically update the price of all listed price feeds whenever the
54
+ triggering condition for a single feed is met. This behavior takes advantage of the reduced cost of batch price updates
55
+ provided by the [Perseus upgrade](https://medium.com/@antonia.vanna.delgado/pyth-network-perseus-first-party-data-matters-e3379bf0d019),
56
+ and is typically the lowest cost way to schedule price updates for multiple feeds.
57
+
58
+ However, if you would like to customize this behavior, you can add an `early_update` section to the YAML configuration file for
59
+ the feed.
60
+
61
+ ```yaml
62
+ - alias: A/USD # Arbitrary alias for the price feed. It is used in enhance logging.
63
+ ...
64
+ # If provided, only early update this price feed if at least one of the listed triggering conditions is met.
65
+ early_update:
66
+ time_difference: 30
67
+ price_deviation: 0.1
68
+ confidence_ratio: 0.5
69
+ ```
70
+
52
71
  Two sample YAML configuration files are available in the root of this repo.
53
72
 
54
73
  You can get the list of available price feeds from
55
74
  [here](https://pyth.network/developers/price-feed-ids/).
56
75
 
76
+ Price pusher communicates with [Hermes][] price service to get the most recent price updates. Hermes listens to the
77
+ Pythnet and Wormhole network to get latest price updates, and serves REST and websocket APIs for consumers to fetch the
78
+ updates. Pyth hosts public endpoints for Hermes; however, it is recommended to get a private endpoint from one of the
79
+ Hermes RPC providers for more reliability. Please refer to [this
80
+ document](https://docs.pyth.network/documentation/pythnet-price-feeds/hermes) for more information.
81
+
57
82
  To run the price pusher, please run the following commands, replacing the command line arguments as necessary:
58
83
 
59
84
  ```sh
@@ -67,8 +92,8 @@ cd price_pusher
67
92
  # For EVM
68
93
  npm run start -- evm --endpoint wss://example-rpc.com \
69
94
  --pyth-contract-address 0xff1a0f4744e8582DF...... \
70
- --price-service-endpoint https://example-pyth-price.com \
71
- --price-config-file "path/to/price-config.testnet.sample.yaml" \
95
+ --price-service-endpoint https://example-hermes-rpc.com \
96
+ --price-config-file "path/to/price-config.beta.sample.yaml" \
72
97
  --mnemonic-file "path/to/mnemonic.txt" \
73
98
  [--pushing-frequency 10] \
74
99
  [--polling-frequency 5] \
@@ -76,17 +101,19 @@ npm run start -- evm --endpoint wss://example-rpc.com \
76
101
 
77
102
  # For Injective
78
103
  npm run start -- injective --grpc-endpoint https://grpc-endpoint.com \
79
- --pyth-contract-address inj1z60tg0... --price-service-endpoint "https://example-pyth-price.com" \
80
- --price-config-file "path/to/price-config.testnet.sample.yaml" \
104
+ --pyth-contract-address inj1z60tg0... --price-service-endpoint "https://example-hermes-rpc.com" \
105
+ --price-config-file "path/to/price-config.beta.sample.yaml" \
81
106
  --mnemonic-file "path/to/mnemonic.txt" \
82
107
  --network testnet \
108
+ [--gas-price 500000000] \
83
109
  [--pushing-frequency 10] \
84
110
  [--polling-frequency 5]
85
111
 
86
112
  # For Aptos
87
113
  npm run start -- aptos --endpoint https://fullnode.testnet.aptoslabs.com/v1 \
88
- --pyth-contract-address 0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387 --price-service-endpoint "https://hermes-beta.pyth.network" \
89
- --price-config-file "./price-config.testnet.sample.yaml" \
114
+ --pyth-contract-address 0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387 \
115
+ --price-service-endpoint "https://example-hermes-rpc.com" \
116
+ --price-config-file "path/to/price-config.beta.sample.yaml" \
90
117
  --mnemonic-file "path/to/mnemonic.txt" \
91
118
  [--pushing-frequency 10] \
92
119
  [--polling-frequency 5]
@@ -99,9 +126,9 @@ npm run start -- sui \
99
126
  --wormhole-package-id 0xcc029e2810f17f9f43f52262f40026a71fbdca40ed3803ad2884994361910b7e \
100
127
  --wormhole-state-id 0xebba4cc4d614f7a7cdbe883acc76d1cc767922bc96778e7b68be0d15fce27c02 \
101
128
  --price-feed-to-price-info-object-table-id 0xf8929174008c662266a1adde78e1e8e33016eb7ad37d379481e860b911e40ed5 \
102
- --price-service-endpoint https://hermes-beta.pyth.network \
129
+ --price-service-endpoint https://example-hermes-rpc.com \
103
130
  --mnemonic-file ./mnemonic \
104
- --price-config-file ./price-config.testnet.sample.yaml \
131
+ --price-config-file ./price-config.beta.sample.yaml \
105
132
  [--pushing-frequency 10] \
106
133
  [--polling-frequency 5] \
107
134
  [--num-gas-objects 30]
@@ -111,6 +138,8 @@ npm run start -- sui \
111
138
  docker run public.ecr.aws/pyth-network/xc-price-pusher:v<version> -- <above-arguments>
112
139
  ```
113
140
 
141
+ [hermes]: https://github.com/pyth-network/pyth-crosschain/tree/main/hermes
142
+
114
143
  ### Command Line Arguments
115
144
 
116
145
  To know more about the arguments the price-pusher accepts. You can run:
@@ -127,14 +156,17 @@ npm run start -- {network} --help
127
156
  For example, to push `BTC/USD` and `BNB/USD` prices on Fantom testnet, run the following command:
128
157
 
129
158
  ```sh
130
- npm run dev -- evm --endpoint https://endpoints.omniatech.io/v1/fantom/testnet/public \
131
- --pyth-contract-address 0xff1a0f4744e8582DF1aE09D5611b887B6a12925C --price-service-endpoint https://hermes-beta.pyth.network \
132
- --mnemonic-file "./mnemonic" --price-config-file "./price-config.testnet.sample.yaml"
159
+ npm run dev -- evm \
160
+ --endpoint https://endpoints.omniatech.io/v1/fantom/testnet/public \
161
+ --pyth-contract-address 0x5744Cbf430D99456a0A8771208b674F27f8EF0Fb \
162
+ --price-service-endpoint https://hermes.pyth.network \
163
+ --mnemonic-file "./mnemonic" \
164
+ --price-config-file "./price-config.stable.sample.yaml"
133
165
  ```
134
166
 
135
- [`price-config.testnet.sample.yaml`](./price-config.testnet.sample.yaml) contains configuration for `BTC/USD`
136
- and `BNB/USD` price feeds on Pyth testnet. [`price-config.mainnet.sample.yaml`](./price-config.mainnet.sample.yaml)
137
- contains the same configuration for `BTC/USD` and `BNB/USD` on Pyth mainnet.
167
+ [`price-config.stable.sample.yaml`](./price-config.stable.sample.yaml) contains configuration for `BTC/USD`
168
+ and `BNB/USD` price feeds on Pyth stable data sources. [`price-config.beta.sample.yaml`](./price-config.beta.sample.yaml)
169
+ contains the same configuration for `BTC/USD` and `BNB/USD` on Pyth beta data sources.
138
170
 
139
171
  You can also provide a config file instead of providing command line options, run the following command:
140
172
 
@@ -144,30 +176,22 @@ npm run start -- injective --config "./config.injective.sample.json"
144
176
 
145
177
  [`config.injective.sample.json`](./config.injective.sample.json) contains configuration to publish on Injective testnet.
146
178
 
147
- ## Running using a standalone price service (via docker-compose)
148
-
149
- Price pusher communicates with [Pyth price service][] to get the most recent price updates. Pyth price service listens to the
150
- Wormhole network to get latest price updates, and serves REST and websocket APIs for consumers to fetch the updates.
151
- Pyth hosts public endpoints for the price service; however, it is recommended to run it standalone to achieve more resiliency and
152
- scalability.
179
+ ## Running via docker-compose
153
180
 
154
- This directory contains sample docker compose files ([testnet](./docker-compose.testnet.sample.yaml),
155
- [mainnet](./docker-compose.mainnet.sample.yaml)) a price pusher and its dependencies, including a
156
- price service and a Wormhole spy. A price service depends on a Wormhole spy. A spy listens to the Wormhole
157
- network and reports all Pyth-related Wormhole messages to the price service.
181
+ This directory contains sample docker compose files ([stable](./docker-compose.stable.sample.yaml),
182
+ [beta](./docker-compose.beta.sample.yaml)) a price pusher.
158
183
 
159
- To run the services via docker-compose, please modify the your target network (testnet, mainnet) sample docker-compose file to adjust the configurations.
184
+ To run the services via docker-compose, please set the RPC endpoint and contract address of your target network in the
185
+ sample docker-compose file.
160
186
 
161
187
  Then, start the docker-compose like this:
162
188
 
163
189
  ```
164
- docker-compose -f docker-compose.testnet.sample.yaml up
190
+ docker-compose -f docker-compose.stable.sample.yaml up
165
191
  ```
166
192
 
167
193
  It will take a few minutes until all the services are up and running.
168
194
 
169
- [pyth price service]: https://github.com/pyth-network/pyth-crosschain/tree/main/price_service/server
170
-
171
195
  ## Reliability
172
196
 
173
197
  You can run multiple instances of the price pusher to increase the reliability. It is better to use
@@ -11,6 +11,7 @@ declare const _default: {
11
11
  "price-config-file": Options;
12
12
  "grpc-endpoint": Options;
13
13
  network: Options;
14
+ "gas-price": Options;
14
15
  };
15
16
  handler: (argv: any) => void;
16
17
  };
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/injective/command.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;oBA2BL,GAAG;;AAxB9B,wBA4FE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/injective/command.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;oBA+BL,GAAG;;AA5B9B,wBAkGE"}
@@ -50,6 +50,10 @@ exports.default = {
50
50
  type: "string",
51
51
  required: true,
52
52
  },
53
+ "gas-price": {
54
+ description: "Gas price to be used for each transasction",
55
+ type: "number",
56
+ },
53
57
  ...options.priceConfigFile,
54
58
  ...options.priceServiceEndpoint,
55
59
  ...options.mnemonicFile,
@@ -59,7 +63,7 @@ exports.default = {
59
63
  },
60
64
  handler: function (argv) {
61
65
  // FIXME: type checks for this
62
- const { grpcEndpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, network, } = argv;
66
+ const { gasPrice, grpcEndpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, network, } = argv;
63
67
  if (network !== "testnet" && network !== "mainnet") {
64
68
  throw new Error("Please specify network. One of [testnet, mainnet]");
65
69
  }
@@ -82,6 +86,7 @@ exports.default = {
82
86
  });
83
87
  const injectivePusher = new injective_1.InjectivePricePusher(priceServiceConnection, pythContractAddress, grpcEndpoint, mnemonic, {
84
88
  chainId: (0, networks_1.getNetworkInfo)(network).chainId,
89
+ gasPrice,
85
90
  });
86
91
  const controller = new controller_1.Controller(priceConfigs, pythListener, injectiveListener, injectivePusher, { pushingFrequency });
87
92
  controller.start();
@@ -7,6 +7,7 @@ export type PriceConfig = {
7
7
  timeDifference: DurationInSeconds;
8
8
  priceDeviation: PctNumber;
9
9
  confidenceRatio: PctNumber;
10
+ customEarlyUpdate: boolean | undefined;
10
11
  earlyUpdateTimeDifference: DurationInSeconds | undefined;
11
12
  earlyUpdatePriceDeviation: PctNumber | undefined;
12
13
  earlyUpdateConfidenceRatio: PctNumber | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"price-config.d.ts","sourceRoot":"","sources":["../src/price-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAI9D,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAmB,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAuBxC,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,SAAS,CAAC;IACd,cAAc,EAAE,iBAAiB,CAAC;IAClC,cAAc,EAAE,SAAS,CAAC;IAC1B,eAAe,EAAE,SAAS,CAAC;IAI3B,yBAAyB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzD,yBAAyB,EAAE,SAAS,GAAG,SAAS,CAAC;IACjD,0BAA0B,EAAE,SAAS,GAAG,SAAS,CAAC;CACnD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAsB/D;AAED,oBAAY,eAAe;IAEzB,GAAG,IAAA;IAEH,KAAK,IAAA;IAEL,EAAE,IAAA;CACH;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,SAAS,GAAG,SAAS,EACxC,iBAAiB,EAAE,SAAS,GAAG,SAAS,GACvC,eAAe,CAmEjB"}
1
+ {"version":3,"file":"price-config.d.ts","sourceRoot":"","sources":["../src/price-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAI9D,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAmB,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAuBxC,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,SAAS,CAAC;IACd,cAAc,EAAE,iBAAiB,CAAC;IAClC,cAAc,EAAE,SAAS,CAAC;IAC1B,eAAe,EAAE,SAAS,CAAC;IAU3B,iBAAiB,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,yBAAyB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzD,yBAAyB,EAAE,SAAS,GAAG,SAAS,CAAC;IACjD,0BAA0B,EAAE,SAAS,GAAG,SAAS,CAAC;CACnD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAuB/D;AAED,oBAAY,eAAe;IAEzB,GAAG,IAAA;IAEH,KAAK,IAAA;IAEL,EAAE,IAAA;CACH;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,SAAS,GAAG,SAAS,EACxC,iBAAiB,EAAE,SAAS,GAAG,SAAS,GACvC,eAAe,CAqEjB"}
@@ -39,6 +39,7 @@ function readPriceConfigFile(path) {
39
39
  timeDifference: priceConfigRaw.time_difference,
40
40
  priceDeviation: priceConfigRaw.price_deviation,
41
41
  confidenceRatio: priceConfigRaw.confidence_ratio,
42
+ customEarlyUpdate: priceConfigRaw.early_update !== undefined,
42
43
  earlyUpdateTimeDifference: priceConfigRaw.early_update?.time_difference,
43
44
  earlyUpdatePriceDeviation: priceConfigRaw.early_update?.price_deviation,
44
45
  earlyUpdateConfidenceRatio: priceConfigRaw.early_update?.confidence_ratio,
@@ -93,8 +94,10 @@ function shouldUpdate(priceConfig, sourceLatestPrice, targetLatestPrice) {
93
94
  confidenceRatioPct >= priceConfig.confidenceRatio) {
94
95
  return UpdateCondition.YES;
95
96
  }
96
- else if ((priceConfig.earlyUpdateTimeDifference !== undefined &&
97
- timeDifference >= priceConfig.earlyUpdateTimeDifference) ||
97
+ else if (priceConfig.customEarlyUpdate === undefined ||
98
+ !priceConfig.customEarlyUpdate ||
99
+ (priceConfig.earlyUpdateTimeDifference !== undefined &&
100
+ timeDifference >= priceConfig.earlyUpdateTimeDifference) ||
98
101
  (priceConfig.earlyUpdatePriceDeviation !== undefined &&
99
102
  priceDeviationPct >= priceConfig.earlyUpdatePriceDeviation) ||
100
103
  (priceConfig.earlyUpdateConfidenceRatio !== undefined &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pythnetwork/price-pusher",
3
- "version": "5.7.1",
3
+ "version": "6.1.0",
4
4
  "description": "Pyth Price Pusher",
5
5
  "homepage": "https://pyth.network",
6
6
  "main": "lib/index.js",
@@ -64,5 +64,5 @@
64
64
  "yaml": "^2.1.1",
65
65
  "yargs": "^17.5.1"
66
66
  },
67
- "gitHead": "44ebfbaf5512acd96a12b3cdf361b47e64802dbf"
67
+ "gitHead": "1be8a02b94d2a09e5284da72e57eb0eb3943d3ae"
68
68
  }