feat(lazer/stellar): add a one-command demo client for the example consumer - #135
Merged
Merged
Conversation
…nsumer The example consumer README told the reader to invoke update_price with a <HEX_ENCODED_UPDATE>, but nothing produced that hex, so the walkthrough could not be run end to end. Add lazer/stellar/client, a standalone Node client that fetches a freshly signed Lazer update, submits it to a deployed example consumer, and reads the stored price back in human units. Rewrite the README walkthrough around it and document the freshness/monotonicity failure modes.
azellers
approved these changes
Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
lazer/stellar/README.mdtold the reader to run-- update_price --payload <HEX_ENCODED_UPDATE>, but nothing in the repo produced that hex, so theexample consumer walkthrough could not be run end to end.
lazer/stellar/client/— a standalone Node client that runs the whole consumer story inone command: fetch a freshly signed Pyth Lazer update, print the update hex and the off-chain
price, submit it to a deployed example consumer's
update_price, then readget_priceback andprint the stored price in human units with a stellar.expert link.
price,exponentandfeedUpdateTimestamp. The consumer reads all three, and aproperty that is not requested decodes to
Noneon-chain, failing the call.@stellar/stellar-sdkand plainfetch, with plain semver deps — it runsoutside the Pyth monorepos, which matters because this is aimed at an external audience.
--network testnet|mainnet,--contract-id,--feed-id,--channel,--lazer-endpoint;signing key from
--secretorSTELLAR_WALLET_SECRET; Lazer token fromPYTH_API_KEY.no secret is given). On mainnet it bids
1000000stroops of inclusion fee, because mainnetledgers run near capacity and a base-fee bid gets evicted.
the raw diagnostics — notably
PriceStale(testing #1) andPriceOutdated(Added growing example #9).lazer/stellar/README.md— the walkthrough now ends in a real command instead of a danglingplaceholder, and documents the freshness and strict-monotonicity failure modes.
.github/workflows/ci-lazer-stellar.yml— a job runningnpm ci && npm test(prettier +tsc) for the client. Static checks only: the demo needs a Lazer token, a funded account and a
live network, so it cannot run in CI.
Why
The consumer walkthrough was the missing link in the Stellar integration story. This makes it
runnable, and the client doubles as the driver for a live demo.
Checks run
Local gate, matching
ci-lazer-stellar.yml:cargo fmt --all -- --check— cleancargo clippy --release --target wasm32v1-none --locked -- --deny warnings— cleancargo build --release --target wasm32v1-none --locked— oknpm ci && npm testinlazer/stellar/client— prettier andtsc --noEmitcleanBecause this drives a live chain, the local gate is not sufficient on its own. The full flow was
executed against both real networks, with the example consumer deployed from this WASM:
Testnet — consumer
CCEZSNTTVRIYXYHBKD2OMBRQI3RP6ZNXFWQ5ZG5ZDTQ7JZ4DTZ6FR72Q, verifierCAYFT5JE3UQTKT4Q6ZOZK4FXVYVT6RE3MFC7STA4UB6WAEGBT65MRU52.update_pricesucceeded in tx14a8052094f9e58bfb510421b728b77a5743ddd399e77a0341742bf1f0aa4f49(ledger 4708537);get_priceread back BTC/USD 75725.44954934.
Mainnet — consumer
CB2XIALZ4IHL6S4BDPA5BERJ6G4ZQL52XI4VRRNOIQ6R3ZM6U6ZIBD3X, verifierCACZ3GBAKUPIAFRILUFO27J5RUH5GJ2VSJ46LP6GJYSKGDRTQ5MS3HCH.update_pricesucceeded in tx9a645c780ca5b5fccc9d3524e2c6bfedd3b8aefaebc84dd3e9def28676526477(ledger 64456352);get_priceread back BTC/USD 75734.23859389.
The error path was exercised too: pointing the client at
--feed-id 2against a contract configuredfor feed 1 produced
contract error #2: FeedMissingwith the actionable explanation.The direct Stellar CLI walkthrough now in the README (curl the payload,
stellar contract invoke update_price, thenget_price) was also run on testnet and returned{"exponent":-8,"price":7566678012269,"timestamp_us":1789566132800000}.