Skip to content

Commit 0f0b91f

Browse files
committed
update
1 parent b5510ea commit 0f0b91f

File tree

18 files changed

+4594
-908
lines changed

18 files changed

+4594
-908
lines changed

apps/entropy-debug/next-env.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
4+
// NOTE: This file should not be edited
5+
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.

apps/entropy-debug/package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "entropy-debug-app",
3+
"version": "0.1.0",
4+
"description": "Debugging tool for entropy",
5+
"private": true,
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/pyth-network/pyth-crosschain",
9+
"directory": "apps/entropy-debug"
10+
},
11+
"publishConfig": {
12+
"access": "public"
13+
},
14+
"scripts": {
15+
"dev": "next dev",
16+
"build": "next build",
17+
"start": "next start",
18+
"lint": "next lint"
19+
},
20+
"license": "Apache-2.0",
21+
"dependencies": {
22+
"@radix-ui/react-select": "^2.1.2",
23+
"@radix-ui/react-slot": "^1.1.0",
24+
"@radix-ui/react-switch": "^1.1.1",
25+
"class-variance-authority": "^0.7.1",
26+
"clsx": "^2.1.1",
27+
"ethers": "^6.13.4",
28+
"highlight.js": "^11.10.0",
29+
"lucide-react": "^0.465.0",
30+
"next": "15.0.3",
31+
"react": "19.0.0-rc-66855b96-20241106",
32+
"react-dom": "19.0.0-rc-66855b96-20241106",
33+
"tailwind-merge": "^2.5.5",
34+
"tailwindcss-animate": "^1.0.7",
35+
"viem": "^2.21.53"
36+
},
37+
"devDependencies": {
38+
"@cprussin/eslint-config": "catalog:",
39+
"@cprussin/jest-config": "catalog:",
40+
"@cprussin/prettier-config": "catalog:",
41+
"@cprussin/tsconfig": "catalog:",
42+
"@types/node": "^20",
43+
"@types/react": "^18",
44+
"@types/react-dom": "^18",
45+
"eslint": "^8",
46+
"eslint-config-next": "15.0.3",
47+
"postcss": "^8",
48+
"tailwindcss": "^3.4.1",
49+
"typescript": "^5"
50+
}
51+
}
25.3 KB
Binary file not shown.
66.3 KB
Binary file not shown.
64.7 KB
Binary file not shown.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
body {
6+
font-family: Arial, Helvetica, sans-serif;
7+
}
8+
9+
@layer base {
10+
:root {
11+
--background: 0 0% 100%;
12+
--foreground: 0 0% 3.9%;
13+
--card: 0 0% 100%;
14+
--card-foreground: 0 0% 3.9%;
15+
--popover: 0 0% 100%;
16+
--popover-foreground: 0 0% 3.9%;
17+
--primary: 0 0% 9%;
18+
--primary-foreground: 0 0% 98%;
19+
--secondary: 0 0% 96.1%;
20+
--secondary-foreground: 0 0% 9%;
21+
--muted: 0 0% 96.1%;
22+
--muted-foreground: 0 0% 45.1%;
23+
--accent: 0 0% 96.1%;
24+
--accent-foreground: 0 0% 9%;
25+
--destructive: 0 84.2% 60.2%;
26+
--destructive-foreground: 0 0% 98%;
27+
--border: 0 0% 89.8%;
28+
--input: 0 0% 89.8%;
29+
--ring: 0 0% 3.9%;
30+
--chart-1: 12 76% 61%;
31+
--chart-2: 173 58% 39%;
32+
--chart-3: 197 37% 24%;
33+
--chart-4: 43 74% 66%;
34+
--chart-5: 27 87% 67%;
35+
--radius: 0.5rem;
36+
}
37+
.dark {
38+
--background: 0 0% 3.9%;
39+
--foreground: 0 0% 98%;
40+
--card: 0 0% 3.9%;
41+
--card-foreground: 0 0% 98%;
42+
--popover: 0 0% 3.9%;
43+
--popover-foreground: 0 0% 98%;
44+
--primary: 0 0% 98%;
45+
--primary-foreground: 0 0% 9%;
46+
--secondary: 0 0% 14.9%;
47+
--secondary-foreground: 0 0% 98%;
48+
--muted: 0 0% 14.9%;
49+
--muted-foreground: 0 0% 63.9%;
50+
--accent: 0 0% 14.9%;
51+
--accent-foreground: 0 0% 98%;
52+
--destructive: 0 62.8% 30.6%;
53+
--destructive-foreground: 0 0% 98%;
54+
--border: 0 0% 14.9%;
55+
--input: 0 0% 14.9%;
56+
--ring: 0 0% 83.1%;
57+
--chart-1: 220 70% 50%;
58+
--chart-2: 160 60% 45%;
59+
--chart-3: 30 80% 55%;
60+
--chart-4: 280 65% 60%;
61+
--chart-5: 340 75% 55%;
62+
}
63+
}
64+
65+
@layer base {
66+
* {
67+
@apply border-border;
68+
}
69+
body {
70+
@apply bg-background text-foreground;
71+
}
72+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { Metadata } from "next";
2+
import localFont from "next/font/local";
3+
import "./globals.css";
4+
5+
const geistSans = localFont({
6+
src: "./fonts/GeistVF.woff",
7+
variable: "--font-geist-sans",
8+
weight: "100 900",
9+
});
10+
const geistMono = localFont({
11+
src: "./fonts/GeistMonoVF.woff",
12+
variable: "--font-geist-mono",
13+
weight: "100 900",
14+
});
15+
16+
export const metadata: Metadata = {
17+
title: "Pyth Entropy Debug App",
18+
description: "Pyth Entropy Debug App",
19+
};
20+
21+
export default function RootLayout({
22+
children,
23+
}: Readonly<{
24+
children: React.ReactNode;
25+
}>) {
26+
return (
27+
<html lang="en">
28+
<body
29+
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
30+
>
31+
{children}
32+
</body>
33+
</html>
34+
);
35+
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import { Switch } from "../components/ui/switch"
5+
import { Input } from "../components/ui/input"
6+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../components/ui/select"
7+
import { useState, useMemo, useCallback, useEffect, useRef } from "react"
8+
import { EntropyDeployments } from "../store/EntropyDeployments"
9+
import { isValidTxHash } from "../lib/utils"
10+
import { requestCallback } from "../lib/revelation"
11+
import hljs from 'highlight.js/lib/core';
12+
import bash from 'highlight.js/lib/languages/bash';
13+
import 'highlight.js/styles/github-dark.css'; // You can choose different themes
14+
15+
// Register the bash language
16+
hljs.registerLanguage('bash', bash);
17+
18+
class BaseError extends Error {
19+
constructor(message: string) {
20+
super(message)
21+
this.name = "BaseError"
22+
}
23+
}
24+
25+
class InvalidTxHashError extends BaseError {
26+
constructor(message: string) {
27+
super(message)
28+
this.name = "InvalidTxHashError"
29+
}
30+
}
31+
32+
33+
enum TxStateType {
34+
NotLoaded,
35+
Loading,
36+
Success,
37+
Error
38+
}
39+
40+
const TxState = {
41+
NotLoaded: () => ({status: TxStateType.NotLoaded as const}),
42+
Loading: () => ({status: TxStateType.Loading as const}),
43+
Success: (data: string) => ({status: TxStateType.Success as const, data}),
44+
Error: (error: unknown) => ({status: TxStateType.Error as const, error}),
45+
}
46+
47+
type TxStateContext = ReturnType<typeof TxState.NotLoaded> | ReturnType<typeof TxState.Loading> | ReturnType<typeof TxState.Success> | ReturnType<typeof TxState.Error>
48+
49+
export default function PythEntropyDebugApp() {
50+
const [state, setState] = useState<TxStateContext>(TxState.NotLoaded());
51+
const [isMainnet, setIsMainnet] = useState<boolean>(false);
52+
const [txHash, setTxHash] = useState<string>("");
53+
const [error, setError] = useState<BaseError | null>(null);
54+
const [selectedChain, setSelectedChain] = useState<string>("");
55+
56+
const validateTxHash = (hash: string) => {
57+
if (!isValidTxHash(hash) && hash !== "") {
58+
setError(new InvalidTxHashError("Transaction hash must be 64 hexadecimal characters"));
59+
} else {
60+
setError(null);
61+
}
62+
setTxHash(hash);
63+
};
64+
65+
const availableChains = useMemo(() => {
66+
return Object.entries(EntropyDeployments)
67+
.filter(([, deployment]) => deployment.network === (isMainnet ? "mainnet" : "testnet"))
68+
.map(([key]) => key);
69+
}, [isMainnet]);
70+
71+
const oncClickFetchInfo = useCallback(() => {
72+
setState(TxState.Loading());
73+
requestCallback(txHash, selectedChain)
74+
.then((data) => {
75+
setState(TxState.Success(data));
76+
})
77+
.catch((error) => {
78+
setState(TxState.Error(error));
79+
});
80+
}, [txHash, selectedChain]);
81+
82+
const Info = ({state}: {state: TxStateContext}) => {
83+
const preRef = useRef<HTMLPreElement>(null);
84+
85+
useEffect(() => {
86+
if (preRef.current && state.status === TxStateType.Success) {
87+
hljs.highlightElement(preRef.current);
88+
}
89+
}, [state]);
90+
91+
switch (state.status) {
92+
case TxStateType.NotLoaded:
93+
return <div>Not loaded</div>
94+
case TxStateType.Loading:
95+
return <div>Loading...</div>
96+
case TxStateType.Success:
97+
return (
98+
<div className="mt-4 p-4 bg-gray-100 rounded w-full max-w-3xl">
99+
<p className="mb-2">Please run the following command in your terminal:</p>
100+
<div className="relative">
101+
<pre
102+
ref={preRef}
103+
className="bg-black text-white p-4 rounded overflow-x-auto whitespace-pre-wrap break-words"
104+
>
105+
<code className="language-bash">{state.data}</code>
106+
</pre>
107+
<button
108+
onClick={() => navigator.clipboard.writeText(state.data)}
109+
className="absolute top-2 right-2 bg-gray-700 text-white px-3 py-1 rounded hover:bg-gray-600"
110+
>
111+
Copy
112+
</button>
113+
</div>
114+
</div>
115+
)
116+
case TxStateType.Error:
117+
return (
118+
<div className="mt-4 p-4 bg-red-100 border border-red-400 rounded">
119+
<div className="text-red-600">{String(state.error)}</div>
120+
</div>
121+
)
122+
}
123+
}
124+
125+
return (
126+
<div className="flex flex-col items-center justify-start h-screen">
127+
<h1 className="text-4xl font-bold mt-8">Pyth Entropy Debug App</h1>
128+
129+
<div className="flex items-center space-x-2 mt-4">
130+
<label htmlFor="network-mode">Testnet</label>
131+
<Switch
132+
id="network-mode"
133+
defaultChecked={false}
134+
onCheckedChange={setIsMainnet}
135+
/>
136+
<label htmlFor="network-mode">Mainnet</label>
137+
</div>
138+
<div className="mt-4">
139+
<Select onValueChange={setSelectedChain} value={selectedChain}>
140+
<SelectTrigger>
141+
<SelectValue placeholder="Select Chain" />
142+
</SelectTrigger>
143+
<SelectContent>
144+
{availableChains.map((chain) => (
145+
<SelectItem key={chain} value={chain}>
146+
{chain.charAt(0).toUpperCase() + chain.slice(1).replace(/-/g, ' ')}
147+
</SelectItem>
148+
))}
149+
</SelectContent>
150+
</Select>
151+
</div>
152+
<div className="mt-4">
153+
<label htmlFor="tx-hash" className="mr-2">Request Transaction Hash:</label>
154+
<Input
155+
minLength={64}
156+
id="tx-hash"
157+
className={`border rounded p-2 w-full ${error ? 'border-red-500' : ''}`}
158+
placeholder="Enter Request Transaction Hash:"
159+
value={txHash}
160+
onChange={(e) => validateTxHash(e.target.value)}
161+
/>
162+
{error && <p className="text-red-500 text-sm mt-1">{error.message}</p>}
163+
</div>
164+
<div className="mt-4">
165+
<button
166+
className="bg-blue-500 text-white p-2 rounded"
167+
onClick={oncClickFetchInfo}
168+
>
169+
Fetch Info
170+
</button>
171+
</div>
172+
<Info state={state} />
173+
</div>
174+
);
175+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { cva, type VariantProps } from "class-variance-authority"
4+
5+
import { cn } from "../../lib/utils"
6+
7+
const buttonVariants = cva(
8+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9+
{
10+
variants: {
11+
variant: {
12+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
13+
destructive:
14+
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
15+
outline:
16+
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17+
secondary:
18+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
19+
ghost: "hover:bg-accent hover:text-accent-foreground",
20+
link: "text-primary underline-offset-4 hover:underline",
21+
},
22+
size: {
23+
default: "h-10 px-4 py-2",
24+
sm: "h-9 rounded-md px-3",
25+
lg: "h-11 rounded-md px-8",
26+
icon: "h-10 w-10",
27+
},
28+
},
29+
defaultVariants: {
30+
variant: "default",
31+
size: "default",
32+
},
33+
}
34+
)
35+
36+
export interface ButtonProps
37+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38+
VariantProps<typeof buttonVariants> {
39+
asChild?: boolean
40+
}
41+
42+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43+
({ className, variant, size, asChild = false, ...props }, ref) => {
44+
const Comp = asChild ? Slot : "button"
45+
return (
46+
<Comp
47+
className={cn(buttonVariants({ variant, size, className }))}
48+
ref={ref}
49+
{...props}
50+
/>
51+
)
52+
}
53+
)
54+
Button.displayName = "Button"
55+
56+
export { Button, buttonVariants }

0 commit comments

Comments
 (0)