Skip to content

Commit 7a01d48

Browse files
authored
feat(lazer): add Pyth Lazer examples (#30)
* chore: add lazer examples * feat(lazer): fix solana contract after moving * forge install: forge-std v1.9.4 * forge install: pyth-crosschain v2.24.2 * forge install: openzeppelin-contracts-upgradeable v5.1.0 * feat(lazer): fix evm example tests
1 parent d1f9e38 commit 7a01d48

17 files changed

+7234
-0
lines changed

.gitmodules

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[submodule "lazer/evm/lib/forge-std"]
2+
path = lazer/evm/lib/forge-std
3+
url = https://github.com/foundry-rs/forge-std
4+
[submodule "lazer/evm/lib/pyth-crosschain"]
5+
path = lazer/evm/lib/pyth-crosschain
6+
url = https://github.com/pyth-network/pyth-crosschain
7+
[submodule "lazer/evm/lib/openzeppelin-contracts-upgradeable"]
8+
path = lazer/evm/lib/openzeppelin-contracts-upgradeable
9+
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable

lazer/evm/.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Compiler files
2+
cache/
3+
out/
4+
5+
# Ignores development broadcast logs
6+
!/broadcast
7+
/broadcast/*/31337/
8+
/broadcast/**/dry-run/
9+
10+
# Docs
11+
docs/
12+
13+
# Dotenv file
14+
.env

lazer/evm/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## pyth-lazer-example-evm
2+
3+
This package is built using [Foundry](https://book.getfoundry.sh/).
4+
5+
This example contract shows how to use Pyth Lazer SDK to verify signatures and parse payloads from Pyth Lazer.

lazer/evm/foundry.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[profile.default]
2+
src = "src"
3+
out = "out"
4+
libs = ["lib"]

lazer/evm/lib/forge-std

Submodule forge-std added at 1eea5ba

lazer/evm/lib/pyth-crosschain

Submodule pyth-crosschain added at fb09981

lazer/evm/remappings.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
forge-std/=lib/forge-std/src/
2+
pyth-lazer/=lib/pyth-crosschain/lazer/contracts/evm/src/
3+
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, console} from "forge-std/Script.sol";
5+
import {StdAssertions} from "forge-std/StdAssertions.sol";
6+
7+
contract ExampleReceiverScript is Script, StdAssertions {
8+
function setUp() public {}
9+
10+
function run() public {}
11+
}

lazer/evm/src/ExampleReceiver.sol

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {console} from "forge-std/console.sol";
5+
import {PythLazer} from "pyth-lazer/PythLazer.sol";
6+
import {PythLazerLib} from "pyth-lazer/PythLazerLib.sol";
7+
8+
contract ExampleReceiver {
9+
PythLazer pythLazer;
10+
uint64 public price;
11+
uint64 public timestamp;
12+
13+
constructor(address pythLazerAddress) {
14+
pythLazer = PythLazer(pythLazerAddress);
15+
}
16+
17+
function updatePrice(bytes calldata update) public {
18+
(bytes memory payload,) = pythLazer.verifyUpdate(update);
19+
(uint64 _timestamp, PythLazerLib.Channel channel, uint8 feedsLen, uint16 pos) =
20+
PythLazerLib.parsePayloadHeader(payload);
21+
console.log("timestamp %d", _timestamp);
22+
console.log("channel %d", uint8(channel));
23+
if (channel != PythLazerLib.Channel.RealTime) {
24+
revert("expected update from RealTime channel");
25+
}
26+
console.log("feedsLen %d", feedsLen);
27+
for (uint8 i = 0; i < feedsLen; i++) {
28+
uint32 feedId;
29+
uint8 num_properties;
30+
(feedId, num_properties, pos) = PythLazerLib.parseFeedHeader(payload, pos);
31+
console.log("feedId %d", feedId);
32+
console.log("num_properties %d", num_properties);
33+
for (uint8 j = 0; j < num_properties; j++) {
34+
PythLazerLib.PriceFeedProperty property;
35+
(property, pos) = PythLazerLib.parseFeedProperty(payload, pos);
36+
if (property == PythLazerLib.PriceFeedProperty.Price) {
37+
uint64 _price;
38+
(_price, pos) = PythLazerLib.parseFeedValueUint64(payload, pos);
39+
console.log("price %d", _price);
40+
if (feedId == 2 && _timestamp > timestamp) {
41+
price = _price;
42+
timestamp = _timestamp;
43+
}
44+
} else if (property == PythLazerLib.PriceFeedProperty.BestBidPrice) {
45+
uint64 _price;
46+
(_price, pos) = PythLazerLib.parseFeedValueUint64(payload, pos);
47+
console.log("best bid price %d", _price);
48+
} else if (property == PythLazerLib.PriceFeedProperty.BestAskPrice) {
49+
uint64 _price;
50+
(_price, pos) = PythLazerLib.parseFeedValueUint64(payload, pos);
51+
console.log("best ask price %d", _price);
52+
} else {
53+
revert("unknown property");
54+
}
55+
}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)