Conversation
…on routes - Updated the example environment file with a new Blockfrost API key. - Refactored server.ts to import configuration values directly from config.js. - Modified script.ts to adjust the path for loading Plutus scripts. - Enhanced health route to include network status in the response. - Improved transaction routes to support dry runs and better error handling. - Updated UTXO route to allow fetching based on wallet or script address. - Adjusted frontend API client to return UTXO data more efficiently.
- Deleted the entire API directory, including configuration files, routes, services, and middleware. - Removed the example environment file and package configuration files. - Cleaned up all related TypeScript files and documentation for a streamlined project structure.
There was a problem hiding this comment.
Pull request overview
Adds a full Cardano + Pyth Lazer demo (“PythFLOW”) including an on-chain Aiken validator, off-chain helpers, and a Next.js pipeline UI, while also updating EVM submodules and rebranding the root README.
Changes:
- Introduce Cardano on-chain validator (Aiken/Plutus V3) for verifying Pyth Lazer updates against a datum condition.
- Add Cardano off-chain tooling (Node/TS) for streaming prices and building lock/spend transactions.
- Add a Next.js UI that visualizes the pipeline, plus docs and a README repo rebrand.
Reviewed changes
Copilot reviewed 76 out of 88 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lazer/evm/lib/openzeppelin-contracts-upgradeable | Update git submodule pointer for OZ upgradeable contracts. |
| lazer/evm/lib/forge-std | Update git submodule pointer for forge-std. |
| lazer/cardano/on-chain/validators/price_validator.ak | Add Aiken validator that reads Pyth Lazer updates and enforces datum price constraints. |
| lazer/cardano/on-chain/plutus.json | Add compiled Plutus blueprint output for the validator. |
| lazer/cardano/on-chain/lib/pyth_types.ak | Add on-chain OracleDatum type definition used by the validator. |
| lazer/cardano/on-chain/aiken.toml | Add Aiken project config and dependencies. |
| lazer/cardano/on-chain/aiken.lock | Add Aiken lockfile pinning dependency resolutions. |
| lazer/cardano/off-chain/tsconfig.json | Add TS config for off-chain Node tool. |
| lazer/cardano/off-chain/src/types/index.ts | Add shared domain types for off-chain nodes (price updates, datum, params). |
| lazer/cardano/off-chain/src/nodes/validator_executor.ts | Add off-chain guard logic mirroring on-chain constraints before submitting tx. |
| lazer/cardano/off-chain/src/nodes/tx_builder.ts | Add Mesh-based tx builder for lock/spend flows (off-chain CLI). |
| lazer/cardano/off-chain/src/nodes/price_fetcher.ts | Add Pyth Lazer websocket subscriber + cache writer (CLI). |
| lazer/cardano/off-chain/src/nodes/price_cache.ts | Add in-memory cache for latest received price update. |
| lazer/cardano/off-chain/src/index.ts | Add CLI entrypoint (feed/lock/spend modes). |
| lazer/cardano/off-chain/src/config.ts | Add env-based configuration for endpoints, Blockfrost, wallet, and validator identifier. |
| lazer/cardano/off-chain/package.json | Add off-chain Node package manifest and deps. |
| lazer/cardano/off-chain/.gitignore | Ignore local env/dist/logs for off-chain tool. |
| lazer/cardano/front/tsconfig.json | Add Next.js/TS config for the UI. |
| lazer/cardano/front/src/types/nodes.ts | Add pipeline node identifiers, state model, and styling metadata. |
| lazer/cardano/front/src/types/index.ts | Add UI/shared domain types for datum, price update, decisions, tx results, wallet info. |
| lazer/cardano/front/src/store/usePipelineStore.ts | Add Zustand store implementing pipeline execution, logging, and confirmations. |
| lazer/cardano/front/src/mock/data.ts | Add mock generators for prices/tx hashes/wallet for mock mode. |
| lazer/cardano/front/src/lib/pyth.ts | Add server-only Pyth Lazer client + in-memory cache + listener fanout. |
| lazer/cardano/front/src/lib/price.ts | Add decision logic and datum builder for UI/API parity. |
| lazer/cardano/front/src/lib/mockApi.ts | Add mock API client implementing the pipeline in-process. |
| lazer/cardano/front/src/lib/constants.ts | Add feed IDs, defaults, explorer URLs, and select options. |
| lazer/cardano/front/src/lib/cardano.ts | Add server-only Mesh SDK code to lock/spend UTxOs and encode datum/redeemers. |
| lazer/cardano/front/src/lib/burnerWallet.ts | Add client-side “burner wallet” mnemonic management via localStorage. |
| lazer/cardano/front/src/lib/api.ts | Add real API client wrapper for Next API routes. |
| lazer/cardano/front/src/graph/initialGraph.ts | Add initial ReactFlow layout and edges for the pipeline visualization. |
| lazer/cardano/front/src/components/shared/Toggle.tsx | Add reusable toggle UI component. |
| lazer/cardano/front/src/components/shared/StatusBadge.tsx | Add node status badge component. |
| lazer/cardano/front/src/components/shared/JsonViewer.tsx | Add collapsible JSON viewer for node I/O inspection. |
| lazer/cardano/front/src/components/shared/CopyButton.tsx | Add click-to-copy button for hashes/addresses. |
| lazer/cardano/front/src/components/panels/WalletPanel.tsx | Add burner wallet panel showing address/balance/script address. |
| lazer/cardano/front/src/components/panels/TxViewerPanel.tsx | Add transaction viewer panel with explorer links and datum summary. |
| lazer/cardano/front/src/components/panels/InspectorPanel.tsx | Add node inspector panel for input/output/error. |
| lazer/cardano/front/src/components/panels/ExecutionLog.tsx | Add execution log panel with auto-scroll. |
| lazer/cardano/front/src/components/panels/DatumPanel.tsx | Add datum + redeemer summary panel. |
| lazer/cardano/front/src/components/panels/ControlsPanel.tsx | Add pipeline controls for thresholds, lock amount, service readiness, reset. |
| lazer/cardano/front/src/components/nodes/TxBuilderNode.tsx | Add TX builder node renderer. |
| lazer/cardano/front/src/components/nodes/PythSourceNode.tsx | Add Pyth source node renderer + SSE live stream display. |
| lazer/cardano/front/src/components/nodes/NormalizeNode.tsx | Add normalize node renderer. |
| lazer/cardano/front/src/components/nodes/ExecutionResultNode.tsx | Add execution result node renderer. |
| lazer/cardano/front/src/components/nodes/DecisionNode.tsx | Add decision engine node renderer. |
| lazer/cardano/front/src/components/nodes/BaseNode.tsx | Add shared node chrome: handles, run button, selection/config modal integration. |
| lazer/cardano/front/src/components/nodes/AikenValidatorNode.tsx | Add validator node renderer summarizing on-chain rules. |
| lazer/cardano/front/src/components/StatusBar.tsx | Add pipeline status/breadcrumb header. |
| lazer/cardano/front/src/components/PipelineGraph.tsx | Add ReactFlow container and dynamic edge coloring by node state/layer. |
| lazer/cardano/front/src/components/PipelineApp.tsx | Add main app layout, panels, keyboard shortcuts, and run FAB. |
| lazer/cardano/front/src/components/NodeConfigModal.tsx | Add per-node config modal with parameters + visual tabs. |
| lazer/cardano/front/src/app/page.tsx | Add client-only entry page that dynamically loads the app. |
| lazer/cardano/front/src/app/layout.tsx | Add root layout with fonts/metadata/globals. |
| lazer/cardano/front/src/app/globals.css | Add theme variables and UI/ReactFlow styles. |
| lazer/cardano/front/src/app/api/wallet/route.ts | Add API route to return wallet/script/network info and balance (Blockfrost-backed). |
| lazer/cardano/front/src/app/api/utxos/route.ts | Add API route to fetch script UTxOs. |
| lazer/cardano/front/src/app/api/tx/spend/route.ts | Add API route to build/submit spend tx with off-chain guard using fresh Pyth payload. |
| lazer/cardano/front/src/app/api/tx/lock/route.ts | Add API route to build/submit lock tx. |
| lazer/cardano/front/src/app/api/tx/confirm/route.ts | Add API route to poll Blockfrost for tx confirmation. |
| lazer/cardano/front/src/app/api/status/route.ts | Add API route to report required service configuration presence. |
| lazer/cardano/front/src/app/api/price/stream/route.ts | Add SSE stream for live price updates to the UI. |
| lazer/cardano/front/src/app/api/price/route.ts | Add API route that returns latest fresh price snapshot. |
| lazer/cardano/front/public/window.svg | Add/restore public asset. |
| lazer/cardano/front/public/vercel.svg | Add/restore public asset. |
| lazer/cardano/front/public/next.svg | Add/restore public asset. |
| lazer/cardano/front/public/globe.svg | Add/restore public asset. |
| lazer/cardano/front/public/file.svg | Add/restore public asset. |
| lazer/cardano/front/postcss.config.mjs | Add Tailwind v4 PostCSS config. |
| lazer/cardano/front/package.json | Add Next.js UI package manifest and deps. |
| lazer/cardano/front/next.config.ts | Add Next config stub. |
| lazer/cardano/front/eslint.config.mjs | Add ESLint configuration for Next + TS. |
| lazer/cardano/front/CLAUDE.md | Add agent pointer file. |
| lazer/cardano/front/AGENTS.md | Add agent guidance file. |
| lazer/cardano/front/.gitignore | Add UI gitignore. |
| lazer/cardano/docs/ui.md | Add UI documentation and run instructions. |
| lazer/cardano/docs/pyth.md | Add Pyth Lazer integration documentation. |
| lazer/cardano/docs/pipeline.md | Add pipeline architecture documentation. |
| lazer/cardano/docs/aiken.md | Add Aiken validator documentation and datum encoding notes. |
| README.md | Rebrand and expand root README to PythFLOW-focused overview. |
| .claude/agents/specialized/blockchain-security-auditor.md | Add specialized agent doc (repo tooling context). |
| .claude/agents/specialized/blockchain-developer.md | Add specialized agent doc (repo tooling context). |
| .claude/agents/engineering/frontend-developer.md | Add engineering agent doc for the UI stack and conventions. |
Comments suppressed due to low confidence (6)
lazer/cardano/front/src/lib/pyth.ts:1
resolvedis referenced before itslet resolved = falsedeclaration (temporal dead zone). If a message arrives before the declaration line executes, this will throw aReferenceError. Movelet resolved = false;aboveaddMessageListener(or use a different synchronization approach) so the callback always sees an initialized binding.
lazer/cardano/front/src/lib/api.ts:1- Sending a full 24-word mnemonic from the browser to server API routes is a high-risk credential disclosure pattern (it can be exfiltrated via client-side XSS, logs, proxies, browser extensions, etc.). Prefer signing in the client with a Cardano wallet connector (CIP-30) and submit only the signed tx (or use a server-side wallet that never exposes secrets to the client); at minimum, ensure mnemonics are never transmitted in non-mock mode.
lazer/cardano/off-chain/src/nodes/tx_builder.ts:1 VALIDATOR_SCRIPT_HASHis named/commented as a hash, but it's being treated as Plutus script code (applyCborEncoding(...)) and then used to derive an address/hash. This will produce an invalid script address (and invalid txs) unless the env var actually contains CBOR/UPLC bytes. Fix by either (a) renaming and requiringVALIDATOR_SCRIPT_CBOR/VALIDATOR_SCRIPT_CODE, or (b) loadingcompiledCodefromplutus.jsonand using that asscript.code.
lazer/cardano/off-chain/src/nodes/price_fetcher.ts:1appendFileSyncin the hot path of a 200ms websocket stream can block the event loop and degrade subscription handling, and will grow an unbounded log file. Consider making logging optional (env flag), buffering writes (async stream), and/or rotating logs to avoid IO contention and disk growth.
lazer/cardano/front/src/lib/burnerWallet.ts:1BlockfrostProvideris imported but not used in this file. Removing the unused import avoids lint noise and makes dependencies clearer.
lazer/cardano/off-chain/src/config.ts:1- Defaulting
PYTH_ACCESS_TOKENto a non-empty placeholder can cause the app to attempt authenticated connections with an invalid token (and makes it harder to detect misconfiguration). Prefer defaulting to an empty string and failing fast with a clear error when missing.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const stream = new ReadableStream({ | ||
| start(controller) { | ||
| const remove = onPriceUpdate((price) => { | ||
| const data = JSON.stringify(price); | ||
| controller.enqueue(encoder.encode(`data: ${data}\n\n`)); | ||
| }); | ||
|
|
||
| const heartbeat = setInterval(() => { | ||
| try { controller.enqueue(encoder.encode(": heartbeat\n\n")); } catch { /* closed */ } | ||
| }, 15_000); | ||
|
|
||
| const cleanup = () => { | ||
| remove(); | ||
| clearInterval(heartbeat); | ||
| }; | ||
|
|
||
| // ReadableStream cancel is called when the client disconnects | ||
| (controller as any)._cleanup = cleanup; | ||
| }, | ||
| cancel(controller: any) { | ||
| controller._cleanup?.(); | ||
| }, | ||
| }); |
There was a problem hiding this comment.
The ReadableStream underlying source cancel callback receives a reason, not the controller. As written, cleanup may never run on client disconnect, leaving onPriceUpdate listeners and heartbeat intervals leaking per connection. Store cleanup in a closure-scoped variable (or use an AbortSignal) and implement cancel(reason) to call that closure cleanup directly; avoid mutating the controller with _cleanup.
| @@ -1,3 +1,41 @@ | |||
| # Pyth Examples | |||
| # PythFLOW | |||
There was a problem hiding this comment.
The PR metadata/title suggests a README fix, but the PR introduces a large Cardano on-chain/off-chain/UI stack and repo rebrand. Please update the PR description/checklist to reflect the actual scope (new example project + docs + UI/backend additions) so reviewers can validate expectations and test instructions.
| This repository contains examples of applications integrating Pyth products and services. No newline at end of file | ||
| **Cardano’s no-code frontier — where your idea becomes protocol.** | ||
|
|
||
| PythFLOW is a visual builder for oracle-aware flows on Cardano: compose pipelines from nodes, connect Pyth price data, and pair off-chain logic with on-chain contracts (Aiken + MeshJS). This repository hosts **Pyth integration examples** and the **PythFLOW** Cardano demo stack. |
There was a problem hiding this comment.
The PR metadata/title suggests a README fix, but the PR introduces a large Cardano on-chain/off-chain/UI stack and repo rebrand. Please update the PR description/checklist to reflect the actual scope (new example project + docs + UI/backend additions) so reviewers can validate expectations and test instructions.
Pyth Examples Contribution
Type of Contribution
Project Information
Project/Example Name:
Pyth Product Used:
Blockchain/Platform:
Description
What does this contribution do?
How does it integrate with Pyth?
What problem does it solve or demonstrate?
Directory Structure (for new examples)
Testing & Verification
How to Test This Contribution
Prerequisites
Setup & Run Instructions
Deployment Information (if applicable)
Network:
Contract Address(es):
Demo URL:
Checklist
Code Quality
Testing
Additional Context
Related Issues
Fixes #
Screenshots/Demo (if applicable)
Notes for Reviewers
Thank you for contributing to Pyth Examples!