Skip to content

Read HNT oracle price on-chain in the HNT-to-DC simulator - #2082

Merged
jthiller merged 2 commits into
mainfrom
claude/helium-pr-1207-review-hmetmv
Sep 9, 2026
Merged

jthiller merged 2 commits into
mainfrom
claude/helium-pr-1207-review-hmetmv

Conversation

@jthiller

@jthiller jthiller commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What

Rewrites the live-price source for the HNT→DC calculator on /tokens/data-credit:

  • src/theme/HntToDcSimulator.jsx no longer opens a WebSocket to hermes.pyth.network. It now subscribes to the keyless heliumtools.org HNT price stream over SSE (EventSource, native reconnect): one snapshot on connect, then a frame only when the price changes. The widget displays the stream's oracle.usd — the on-chain Pyth price the Data Credits program reads.
  • Fallback: if the stream errors before ever delivering a price, the widget does a single one-time Solana RPC read of the same oracle — it resolves the current oracle address from the on-chain DataCreditsV0 account and parses the Pyth PriceUpdateV2 account directly — so the price still renders with no standing third-party dependency beyond the stream.
  • Removes @pythnetwork/price-service-client (this widget was its only consumer) and regenerates yarn.lock.
  • One-sentence prose touch on docs/tokens/data-credit.mdx to say the price comes from the on-chain Pyth feed used by the Data Credits program.

UI, CSS, and labels are unchanged.

Why

Pyth's unauthenticated Hermes endpoint stops serving keyless traffic on 2026-08-18. After that date the widget's live price would silently die — liveHntPrice stays 0 and the "Set Live Oracle Price" button never renders, with no visible error.

Streaming keeps Solana RPC load at zero in the steady state (no per-tab polling), while the on-chain fallback keeps the widget self-sufficient if the stream is unreachable. Both paths track oracle rotations automatically: the stream serves whatever account DataCreditsV0 points at, and the fallback resolves that pointer itself — which is how the widget already followed the helium/helium-program-library#1207 cutover (old 4Ddm…J33 → new He5m…89A5, executed on mainnet) with no docs change.

Notes for reviewers

  • Failure mode is unchanged: if neither the stream nor the fallback yields a price, the live-price button stays hidden and the simulator slider still works — identical to today's degraded behavior.
  • The fallback parser fails closed: it verifies the account's feed ID against the known HNT/USD feed (0x649f…9756) and rejects anything that doesn't match, so a layout drift can't render a garbage price.
  • Payloads are handled defensively: the stream's spot block can be null; the widget type-checks oracle.usd before applying it, and a fallback response can't overwrite a fresher stream price that arrived while the RPC read was in flight.
  • Verified: live-tested in a browser — stream path renders the price instantly with 0 RPC calls; pointing the stream at a dead URL fired exactly one 2-call RPC fallback that rendered the identical price (both paths read the same oracle account). Byte offsets confirmed empirically against mainnet. yarn build and Prettier pass.

🤖 Generated with Claude Code

Pyth's unauthenticated Hermes endpoint (hermes.pyth.network) stops serving
keyless traffic on 2026-08-18, which would silently kill the live price in
the /tokens/data-credit calculator. Instead of streaming from Hermes, the
widget now polls Solana RPC every 30s: it resolves the current oracle from
the on-chain DataCreditsV0 account (so it follows oracle rotations like
helium/helium-program-library#1207 automatically) and parses the Pyth
PriceUpdateV2 account directly. Any parse or fetch failure falls back to
the existing behavior of hiding the live-price button.

Removes the now-unused @pythnetwork/price-service-client dependency.
Polling Solana RPC from every open docs tab puts avoidable load on the
RPC proxy. The widget now subscribes to the heliumtools.org HNT price
stream (SSE: one snapshot on connect, then a frame only when the price
changes) and uses its on-chain oracle value. If the stream errors before
ever delivering a price, the widget falls back to a single Solana RPC
read of the same oracle account, so the price still renders with no
standing dependency beyond the stream.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying heliumdocs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 63948a2
Status: ✅  Deploy successful!
Preview URL: https://5d772e23.heliumdocs.pages.dev
Branch Preview URL: https://claude-helium-pr-1207-review.heliumdocs.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Both pricing paths use the headline oracle price rather than the conservative price used by the Data Credits program, and the fallback accepts partially verified updates.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Updates the HNT-to-DC simulator to source pricing from the on-chain oracle via SSE with an RPC fallback.

Changes:

  • Replaces Hermes WebSocket pricing with an SSE stream and Solana fallback.
  • Removes the unused Pyth price-service dependency.
  • Updates Data Credit documentation to describe the on-chain price source.
File summaries
File Description
src/theme/HntToDcSimulator.jsx Implements SSE pricing and on-chain fallback parsing.
docs/tokens/data-credit.mdx Documents the on-chain Pyth feed.
package.json Removes the Pyth client dependency.
yarn.lock Removes the dependency and its transitive packages.
Review details

Suppressed comments (2)

src/theme/HntToDcSimulator.jsx:53

  • This fallback has the same payout mismatch: it decodes the message’s headline price, while mint_data_credits_v0 uses the later ema_price field minus twice ema_conf. As written, fallback results overstate the DC yield and will disagree with the corrected stream path. Decode the EMA fields and apply the program’s confidence adjustment.
    const price = view.getBigInt64(offset, true)
    offset += 8 + 8 // skip conf
    const exponent = view.getInt32(offset, true)
    const scaledPrice = Number(price) * 10 ** exponent
    return Number.isFinite(scaledPrice) && scaledPrice > 0 ? scaledPrice : null

src/theme/HntToDcSimulator.jsx:109

  • The stream contract explicitly says oracle.usd is only the headline posted price; the Data Credits program mints from ema_price - 2 × ema_conf. Feeding oracle.usd into this calculator therefore overstates “DC from 1 HNT.” Use the service’s oracle.mint_price_usd (or refactor around dc_per_hnt) so the displayed conversion matches an actual burn.
        applyPrice(JSON.parse(event.data)?.oracle?.usd)
  • Files reviewed: 3/4 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +37 to +41
if (verificationTag === 0) {
offset += 1
} else if (verificationTag !== 1) {
return null
}
@jthiller
jthiller merged commit 4fef1ac into main Sep 9, 2026
2 checks passed
@jthiller
jthiller deleted the claude/helium-pr-1207-review-hmetmv branch September 9, 2026 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants