@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-
|
|
71
|
-
--price-config-file "path/to/price-config.
|
|
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-
|
|
80
|
-
--price-config-file "path/to/price-config.
|
|
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
|
|
89
|
-
--price-
|
|
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-
|
|
129
|
+
--price-service-endpoint https://example-hermes-rpc.com \
|
|
103
130
|
--mnemonic-file ./mnemonic \
|
|
104
|
-
--price-config-file ./price-config.
|
|
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
|
|
131
|
-
|
|
132
|
-
|
|
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.
|
|
136
|
-
and `BNB/USD` price feeds on Pyth
|
|
137
|
-
contains the same configuration for `BTC/USD` and `BNB/USD` on Pyth
|
|
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
|
|
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 ([
|
|
155
|
-
[
|
|
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
|
|
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.
|
|
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
|
|
@@ -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
|
|
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"}
|
package/lib/injective/command.js
CHANGED
|
@@ -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();
|
package/lib/price-config.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/lib/price-config.js
CHANGED
|
@@ -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 (
|
|
97
|
-
|
|
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": "
|
|
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": "
|
|
67
|
+
"gitHead": "1be8a02b94d2a09e5284da72e57eb0eb3943d3ae"
|
|
68
68
|
}
|