These are Pyth’s offered track at the upcoming EthGlobalOnline hackathon: https://ethglobal.com/events/ethonline2025/prizes/pyth so, I am just trying to make sure that if I build my DAPP with historic prices, that it will qualify for the first track (as seen in the link) or:
Hi,
If you will parse historic Price on chain using either parsePriceFeedUpdates or parsePriceFeedUpdatesUnique, then you will be eligible for the bounty.
Perfect! Is this confirmed? I just want to be absolutely sure to avoid building something that won’t meet the qualification requirements.
Thanks
it is confirmed
Looking forward to see your project.
Perfect! Looking at the docs now. Both of these methods will provide historical prices in an interval (e.g. 60 prices for every second from epoch stamp 1760294000 to 1760294060) but none of those will ACTUALLY update the price on chain for that price feed, right?
What if I need to have last 60 historical price values up to the very latest (now)?
Do I need two seprate calls here? First to update the price on chain with pyth.updatePriceFeeds{ value: fee }(priceUpdate) and then parsePriceFeedUpdates(…) to get the historical price values I need?
Am I thinking right here? Or is there some other way?
Thanks.
You don’t need to update the prices. But if you need 60 historical prices to be verified on-chain, you need parse them.
So, I am using benchmarks API which returns:
```
[
{
“binary”: {
“encoding”: “hex”,
“data”: [
“504e41550100000003b801000000040d00ff95abc1f273ea6c1f906c14d0f078478c931655a028d719e50c62665602103c3022d41f64e5ce8036de985a8e5a697ff3ac28a2d3f5f8416b5c98bbb3ec6af20102edc8773800259b65d49aa7f79c6c3a64ed117b0334eb80713fd65c1474540b29089a4e98b683d5ae8f38c1979855719b2eb8143dd4170c8573044c1d2c3553f5010337edd9e8a0388ab73f56ecb561e2d81b1ae05ce376643657662f7536e3a285424b2dc3fe5957f83c603f340c90a8c3de027cc4913cda4f8811a28a38aa6e7aa70104567a5865bfb72b03be69ca2cdd50f040f92c896e4f4a8dad598fc19e19d2272774b9ed7c23516e4beeeb10ba18adeb841d861b4274167aeb352e2d5f66b63f450006314f528e9cf8292a5315dc1b554be7a3aaacb9ff4a3a3f3d8f542c07bdec65a8398f058bafe7d56dcd22599b353523ac950437b2b0521f47977c8f694f38027f01084aca963b71b3d8d2d1f832ba60addd6e62cf87e13033a14dd5c6f31e96b817391df2ece3a9ddc7ad9877f4ddd0e198428296941dbb3713771f7b68d995bc5091010acda47312abef5212e26a35a29d807f36cf70c2fc664970615efe551f5698d6e0254d2af5b1140dcc25dd768882639b986efb92f8bab2a3e72de6a2a424f357a0000bfe8b251ec6d5075a769df696293fc3b6fca1244322057bfd47c9daa8e748259f0c471a3e79e6d57104b7961ba30e3bcce07a692d15506743d566ccbb91643df4010c17b13a3e8f7cdf07e0ac2039bf77425e7db71daae06a765d4d70e1ea4a1ab22008b865661cae0d4434e38f5eb6950b35359a12ab180608906b5f58414ac530d2000d2ae00a7f262cb046d333307e6a0cac3ff9d40dc1e1144bceb437f93d494a9c0c1a5b5e2acde0c170d0379d00321deff42b9274c49a4343365f6f261250c36a80010e54b6d35e5ee372f4d5951cbe32ca3c2d1d90593acc0f6f0d61fcdc8017f3424f5379d708620e2e23a822a2ca4606e30e2806765b6194f06a4587814d646ea8360010ac4ec95c12e083f92c223e21f2df3a1fb31bdf35b267b9fa722bcd071cbcfa5737a3df134bb43c3388290215507520351e6cfc1df4f1945a4a1cf7fd9496b11300118033b329471128b5e2529b3ac52794de67466049a47a4afd9bb3a64ee52139da0fd458e3a5a4774fd3966573e5ae3053310de3bb4dabe8dff8a76ed42b0f9bd90168f38f8300000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa710000000009d1b8c3014155575600000000000edf59c000002710a490de13f4cb4f7703810aa14bf839b23780ff5d02005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000005a5d3969810000000007533d0dfffffff80000000068f38f830000000068f38f820000005a60205bb0000000000798ad940dc2ec2928270934bf076c89ed9504f548b13855252d32c77b6e796d14548a46644bbbce1823f3d1e1fed4b4825fc41b4ae50da5320d05e02cc3373eea54a83b64e78bc1e8c5bbca36ba667c39164334066c22d5f219a44017266f3590d3652f33d7a6ab732d12a9d6481401ed8eb4d2cfbde6791180b539b2f766753f22e31d375bfd38ff07aa28068bb925b9c5fce7916269b4abfc1ebe91e7acf3b960eee2c92885338354bfb6edb17b8666ae54bb1962d5534c3698ba66c2216b4047602295543ae837620d8ad7e70eb642640e329f2be977d555674e2b186fb995d550b85bc498b41b87aa5f34e7a5164e4e3b4062d8eb0922a3c51b64e354c300bf1af2d7089d9db5005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000005a5d3969810000000007533d0dfffffff80000000068f38f830000000068f38f820000005a60205bb0000000000798ad940dc2ec2928270934bf076c89ed9504f548b13855252d32c77b6e796d14548a46644bbbce1823f3d1e1fed4b4825fc41b4ae50da5320d05e02cc3373eea54a83b64e78bc1e8c5bbca36ba667c39164334066c22d5f219a44017266f3590d3652f33d7a6ab732d12a9d6481401ed8eb4d2cfbde6791180b539b2f766753f22e31d375bfd38ff07aa28068bb925b9c5fce7916269b4abfc1ebe91e7acf3b960eee2c92885338354bfb6edb17b8666ae54bb1962d5534c3698ba66c2216b4047602295543ae837620d8ad7e70eb642640e329f2be977d555674e2b186fb995d550b85bc498b41b87aa5f34e7a5164e4e3b4062d8eb0922a3c51b64e354c300bf1af2d7089d9db5”
]
},
“parsed”: [
{
“id”: “ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace”,
“price”: {
“conf”: “122895629”,
“expo”: -8,
“price”: “388111100289”,
“publish_time”: 1760792451
},
“ema_price”: {
“conf”: “127446420”,
“expo”: -8,
“price”: “388159790000”,
“publish_time”: 1760792451
},
“metadata”: {
“slot”: 249518528,
“proof_available_time”: 1760792452,
“prev_publish_time”: 1760792450
}
},
{
“id”: “ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace”,
“price”: {
“conf”: “122895629”,
“expo”: -8,
“price”: “388111100289”,
“publish_time”: 1760792451
},
“ema_price”: {
“conf”: “127446420”,
“expo”: -8,
“price”: “388159790000”,
“publish_time”: 1760792451
},
“metadata”: {
“slot”: 249518528,
“proof_available_time”: 1760792452,
“prev_publish_time”: 1760792450
}
}
]
},
{
“binary”: {
“encoding”: “hex”,
“data”: [
“504e41550100000003b801000000040d001428991f7d43fabb288a395b5dc4c03f51b6a476206337c168e1568bdce2579771dc7193a5aa1b5baafbf82b0d5f326018785a5f4d714f1eca9077c309b816e9010211958a44ab3db9a3410c6b0eb5b3ec4200cfc5e3da3016db9af214c02922f19b593ef46aa917c59ae22b65710c622b70b6b8e821d276fd91ed4d96471271ea580003378403000f25810d13420c58577ae1467a4fa9b2da5e0c44158c3cd5ce7bed7479d6f406205116d3b52fee330e4684d96b4b77b57dab9f32dbd43bf7e114eaa5000479802c4b17808d769f65e95e233b468a12c9117a32f70b7faa7cc301a1b185c671a5ae470e376c891a767bce89a33d18415e167740dfc100820ad7096ba54a3901067f4c6a350f4450c91ac72ef3e86f228a508a8c5bfbad63868ee003ee4083fabc22e762e457e2c743306f906c8e0cb4bb1bc70ece6c583aa4f0b5ce7ed2211596000851ed2d008eb92f11478623d866ef0be321e6851a904696c9061f23da06134efd57616fc291fb577da7548e03fe0a248bd96311f62c1b76f5c23ff62c2f005ef3000a5b1bea9172c3f22b1de93881c356845edba2344217626453b57a27707d051cd7040f8e6ff3319584a6c25050447727455996635666e11a281de2500118d0dc52010bef349eb8de625e641014b79a2cb766bed88ca02b1df6ca7c73e4cf9e67f7cbe8417c764cd84c132dc1d4cf7997159a06245378e62387a80de8324f9e58faff34010cd4917b8f68f037246367fd19db214cc187656ea2f765e88dd07729ea419e55bd0d5426a40b8fe9d27d5e178707cdba10259725e3b0c677b27f9be219b6170fb0010d8259fbef03dfbc1ac9a7b4fb085db0b4343583c202b699a1acb9eb5b4772a85c602d666d7af69091304ae95a8eca681811468c63876ea014e68700b1aae20b0e010f8e5645cd99bc2ad990097554b39b12a7262cdec7be29dc149e7bd20452b9a9520cec9ea1b2cce87986450d815798ff963e348fc78249196390fd9a253d6a16ba00108cba568e308e8b5e828fd3869452a01a57d330635a9b174e56023a6e959c79af3aef3868a857d1e0a45291fbc00aaab9b944430f498338fe016daae00728596101116e7b022947c1f864022fe6b73b89fcd984482eeda9e63aa1c7d0c6e9c999088d789b905c644ed7717aea85b3d6339629b7571a3d0fe6852a83976bff6445d09f0168f38f8400000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa710000000009d1b8c6014155575600000000000edf59c3000027102d33c0a3a41ee75c7147583fe1857fc6df024f5f02005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000005a5bf3b92f00000000077ccd85fffffff80000000068f38f840000000068f38f830000005a60200d90000000000798a9340d41f7a9d77dd155901b0669d8ab8821f0a382152c2d32c77b6e796d14548a46644bbbce1823f3d1e1fed4b4825fc41b4ae50da5320d05e02cc3373eea0cd21aa98c557c92c6e566886b022b9d090ae2e06f2e094d0691b8945bf990669e817d701c49c3cf3abeb9b5d305c977cb5bce7a9cf772ca97791ba4652988523bfaecafef2845777748fa270b60355e59a0eb28d73121841dfe0591ae0bb89ee00d1017d0c197723bd22798b35b626c502ff9b3385add71351447228a7966bb28b20b042a2ad0d03bb08e8f98b343bd1dddaab3316395461029b6a9fcb1266a96cc6675fefe740935c130a8ec0b244fa25e5ed33937772b3b3ead3695d555c3dc2038d0b5dcbd12005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000005a5bf3b92f00000000077ccd85fffffff80000000068f38f840000000068f38f830000005a60200d90000000000798a9340d41f7a9d77dd155901b0669d8ab8821f0a382152c2d32c77b6e796d14548a46644bbbce1823f3d1e1fed4b4825fc41b4ae50da5320d05e02cc3373eea0cd21aa98c557c92c6e566886b022b9d090ae2e06f2e094d0691b8945bf990669e817d701c49c3cf3abeb9b5d305c977cb5bce7a9cf772ca97791ba4652988523bfaecafef2845777748fa270b60355e59a0eb28d73121841dfe0591ae0bb89ee00d1017d0c197723bd22798b35b626c502ff9b3385add71351447228a7966bb28b20b042a2ad0d03bb08e8f98b343bd1dddaab3316395461029b6a9fcb1266a96cc6675fefe740935c130a8ec0b244fa25e5ed33937772b3b3ead3695d555c3dc2038d0b5dcbd12”
]
},
…
```
and my assumption is that I need to construct a bytes[] array of binary.data fields
and pass it to:
function parsePriceFeedUpdates( bytes[] calldata updateData, bytes32[] calldata priceIds, uint64 minPublishTime, uint64 maxPublishTime ) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);
But I am getting:
❯ cast 4byte 0xe69ffece
InvalidUpdateData()
So, seems like it doesn’t like the format.
just following up on my last message
@Aditya520 @nidhi Could you please take a look sooner than later, because the hackathon submission is at the end of the week…
How are you constructing the bytes[ ] array?
Please DO NOT construct the bytes array manually. Please parse the update that you receive from the history api.
Since you can only pass one timestamp in /v2/updates/price/{publish_time}, you have to parse updates one at a time for every timestamp.
On the other hand, you can parse multiple prices of same timestamp in one call.
edit: added DO NOT
I am parsing it manually. The above output comes from the history API. I then parse it to construct the bytes array out of individual binary.data fields.
assuming the output from the history API is saved in historical_price_update.json , this is how I construct the bytes array:
`
string memory json = vm.readFile("cache/historical_price_update.json");
// Decode entire array
PriceUpdate[] memory updates = abi.decode(vm.parseJson(json, ""), (PriceUpdate[]));
console2.log("Number of updates:", updates.length);
// Flatten all binary.data entries into a bytes[] array
bytes[] memory allUpdates = new bytes[](updates.length);
for (uint256 i = 0; i < updates.length; i++) {
allUpdates[i] = updates[i].binary.data[0];
}
`
I am extremely sorry for the wrong message above.
Please do not construct the bytes array manually
If I don’t construct it manually, how else would I do it?
I query the Benchmarks API:
`
BASE_URL = “https://benchmarks.pyth.network/v1/updates/price”
timestamp = int(time.time()) - 60
interval = 2
price_feed_id = “0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace”
url = f"{BASE_URL}/{timestamp}/{interval}"
params = {“ids”: price_feed_id}
response = requests.get(url, params=params)
`
and get back the exact json I posted above.
Yes this is correct.
this is not.
// Flatten all binary.data entries into a bytes[] array
bytes[] memory allUpdates = new bytes[](updates.length);
for (uint256 i = 0; i < updates.length; i++) {
allUpdates[i] = updates[i].binary.data[0];
}
You can just send the update to parsePriceFeedUpdates
I am soooo confused right now. You just said not to construct the bytes array manually.
How do I construct it then?
Could you provide CONCRETE examples PLEASE
I apologize for the confusion.
You don’t need to construct the bytes array at all.
You fetch the bytes array using
BASE_URL = “https://benchmarks.pyth.network/v1/updates/price{timestamp}”
You will receive an update.
504e41550100000003b801000000040d001428991f7d43fabb288a395b5dc4c03f51b6a476206337c168e1568bdce2579771dc7193a5aa1b5baafbf82b0d5f326018785a5f4d714f1eca9077c309b816e9010211958a44ab3db9a3410c6b0eb5b3ec4200cfc5e3da3016db9af214c02922f19b593ef46aa917c59ae22b65710c622b70b6b8e821d276fd91ed4d96471271ea580003378403000f25810d13420c58577ae1467a4fa9b2da5e0c44158c3cd5ce7bed7479d6f406205116d3b52fee330e4684d96b4b77b57dab9f32dbd43bf7e114eaa5000479802c4b17808d769f65e95e233b468a12c9117a32f70b7faa7cc301a1b185c671a5ae470e376c891a767bce89a33d18415e167740dfc100820ad7096ba54a3901067f4c6a350f4450c91ac72ef3e86f228a508a8c5bfbad63868ee003ee4083fabc22e762e457e2c743306f906c8e0cb4bb1bc70ece6c583aa4f0b5ce7ed2211596000851ed2d008eb92f11478623d866ef0be321e6851a904696c9061f23da06134efd57616fc291fb577da7548e03fe0a248bd96311f62c1b76f5c23ff62c2f005ef3000a5b1bea9172c3f22b1de93881c356845edba2344217626453b57a27707d051cd7040f8e6ff3319584a6c25050447727455996635666e11a281de2500118d0dc52010bef349eb8de625e641014b79a2cb766bed88ca02b1df6ca7c73e4cf9e67f7cbe8417c764cd84c132dc1d4cf7997159a06245378e62387a80de8324f9e58faff34010cd4917b8f68f037246367fd19db214cc187656ea2f765e88dd07729ea419e55bd0d5426a40b8fe9d27d5e178707cdba10259725e3b0c677b27f9be219b6170fb0010d8259fbef03dfbc1ac9a7b4fb085db0b4343583c202b699a1acb9eb5b4772a85c602d666d7af69091304ae95a8eca681811468c63876ea014e68700b1aae20b0e010f8e5645cd99bc2ad990097554b39b12a7262cdec7be29dc149e7bd20452b9a9520cec9ea1b2cce87986450d815798ff963e348fc78249196390fd9a253d6a16ba00108cba568e308e8b5e828fd3869452a01a57d330635a9b174e56023a6e959c79af3aef3868a857d1e0a45291fbc00aaab9b944430f498338fe016daae00728596101116e7b022947c1f864022fe6b73b89fcd984482eeda9e63aa1c7d0c6e9c999088d789b905c644ed7717aea85b3d6339629b7571a3d0fe6852a83976bff6445d09f0168f38f8400000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa710000000009d1b8c6014155575600000000000edf59c3000027102d33c0a3a41ee75c7147583fe1857fc6df024f5f02005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000005a5bf3b92f00000000077ccd85fffffff80000000068f38f840000000068f38f830000005a60200d90000000000798a9340d41f7a9d77dd155901b0669d8ab8821f0a382152c2d32c77b6e796d14548a46644bbbce1823f3d1e1fed4b4825fc41b4ae50da5320d05e02cc3373eea0cd21aa98c557c92c6e566886b022b9d090ae2e06f2e094d0691b8945bf990669e817d701c49c3cf3abeb9b5d305c977cb5bce7a9cf772ca97791ba4652988523bfaecafef2845777748fa270b60355e59a0eb28d73121841dfe0591ae0bb89ee00d1017d0c197723bd22798b35b626c502ff9b3385add71351447228a7966bb28b20b042a2ad0d03bb08e8f98b343bd1dddaab3316395461029b6a9fcb1266a96cc6675fefe740935c130a8ec0b244fa25e5ed33937772b3b3ead3695d555c3dc2038d0b5dcbd12005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000005a5bf3b92f00000000077ccd85fffffff80000000068f38f840000000068f38f830000005a60200d90000000000798a9340d41f7a9d77dd155901b0669d8ab8821f0a382152c2d32c77b6e796d14548a46644bbbce1823f3d1e1fed4b4825fc41b4ae50da5320d05e02cc3373eea0cd21aa98c557c92c6e566886b022b9d090ae2e06f2e094d0691b8945bf990669e817d701c49c3cf3abeb9b5d305c977cb5bce7a9cf772ca97791ba4652988523bfaecafef2845777748fa270b60355e59a0eb28d73121841dfe0591ae0bb89ee00d1017d0c197723bd22798b35b626c502ff9b3385add71351447228a7966bb28b20b042a2ad0d03bb08e8f98b343bd1dddaab3316395461029b6a9fcb1266a96cc6675fefe740935c130a8ec0b244fa25e5ed33937772b3b3ead3695d555c3dc2038d0b5dcbd12
Append 0x to the bytes, and send it to parsePriceFeedUpdates.
You can message me on my tg here.
