Skip to content

Commit c63cd39

Browse files
authored
Merge pull request #1397 from input-output-hk/fix-explorer-sanchonet-respin
Switch explorer to run on preview & clear TVL on Finalized
2 parents fcc1c40 + 87dbfa5 commit c63cd39

File tree

12 files changed

+111
-28
lines changed

12 files changed

+111
-28
lines changed

.github/workflows/explorer/docker-compose.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ services:
44
cardano-node:
55
image: ghcr.io/intersectmbo/cardano-node:8.9.0
66
volumes:
7-
- /srv/var/cardano/state-sanchonet:/data
7+
- /srv/var/cardano/state-preview:/data
88
environment:
99
- CARDANO_CONFIG=/data/config.json
1010
- CARDANO_TOPOLOGY=/data/topology.json
@@ -19,14 +19,14 @@ services:
1919
hydra-explorer:
2020
image: ghcr.io/input-output-hk/hydra-explorer:unstable
2121
volumes:
22-
- /srv/var/cardano/state-sanchonet:/data
22+
- /srv/var/cardano/state-preview:/data
2323
ports:
2424
- "80:8080"
2525
command:
2626
[ "--node-socket", "/data/node.socket"
27-
, "--testnet-magic", "4"
27+
, "--testnet-magic", "2"
2828
, "--api-port", "8080"
2929
# NOTE: Block in which current master scripts were published
30-
, "--start-chain-from", "21830575.4fa28d6c6f6541fd5c73d715d69f3dd7751e7b4d7dc1213cb02d30c5a0db609b"
30+
, "--start-chain-from", "45386581.4a362bfca7cf840575c17b6cbb531588bc8e907beb5a6a28890877fb16be1cd3"
3131
]
3232
restart: always

hydra-explorer/web/.env

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
NETWORK_URL=preview

hydra-explorer/web/next.config.mjs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/** @type {import('next').NextConfig} */
22
const nextConfig = {
3-
output: 'export'
4-
};
3+
output: 'export',
4+
env: {
5+
NETWORK_URL: process.env.NETWORK_URL
6+
},
7+
};
58

69
export default nextConfig;

hydra-explorer/web/src/app/page.tsx

+14-8
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import TickBox from "@/components/TickBox"
77
import HeadsTable from "@/components/HeadsTable"
88
import { HeadsDataProvider } from "@/providers/HeadsDataProvider"
99
import HeadsDashboard from "@/components/HeadsDashboard"
10+
import { CardanoExplorerProvider } from "@/providers/CardanoExplorer"
1011

1112

1213
export default function Home() {
14+
1315
return (
1416
<main className="items-center">
1517
<div className="">
@@ -42,16 +44,20 @@ export default function Home() {
4244
</div>
4345
</div>
4446

45-
<div className="flex items-start space-x-4">
46-
<div>
47-
<TickBox />
48-
</div>
49-
<div>
50-
<IntervalSetter />
47+
<CardanoExplorerProvider network={process.env.NETWORK_URL || "preview"}>
48+
<div className="flex items-start space-x-4">
49+
<div>
50+
<TickBox />
51+
</div>
52+
<div>
53+
<IntervalSetter />
54+
</div>
55+
5156
</div>
57+
<HeadsTable />
58+
</CardanoExplorerProvider>
59+
5260

53-
</div>
54-
<HeadsTable />
5561
</HeadsDataProvider>
5662
</div>
5763

hydra-explorer/web/src/components/HeadDetails/index.tsx

+14-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import React, { useState, useEffect } from 'react'
44
import { HeadState, HeadMember } from '@/app/model'
55
import MemberCommitDetails from '../MemberCommitDetails'
6+
import { useCardanoExplorer } from '@/providers/CardanoExplorer'
67

78
interface HeadDetailsProps {
89
head: HeadState
@@ -36,6 +37,8 @@ const HeadDetails: React.FC<HeadDetailsProps> = ({ head, onClose }) => {
3637
}
3738
}, [onClose, showMemberCommitDetails])
3839

40+
const explorer = useCardanoExplorer()
41+
3942
return (
4043
<div className="fixed inset-0 flex items-center justify-center bg-gray-900 bg-opacity-50 z-50">
4144
<div className="bg-gray-800 p-6 rounded-lg shadow-xl relative overflow-auto max-h-screen">
@@ -50,17 +53,23 @@ const HeadDetails: React.FC<HeadDetailsProps> = ({ head, onClose }) => {
5053
<div className="border p-4">
5154
<h3 className="text-lg font-semibold mb-2">Head ID</h3>
5255
<p>
53-
<a href={`https://sancho.cexplorer.io/policy/${head.headId}/mint`} target="_blank" className="text-blue-300 hover:text-blue-500">
56+
<a href={explorer.mintPolicy(head.headId)} target="_blank" className="text-blue-300 hover:text-blue-500">
5457
{head.headId}
5558
</a>
5659
</p>
5760
</div>
5861
<div className="border p-4">
5962
<h3 className="text-lg font-semibold mb-2">Seed Tx In</h3>
6063
<p>
61-
<a href={`https://sancho.cexplorer.io/tx/${head.seedTxIn}`} target="_blank" className="text-blue-300 hover:text-blue-500">
62-
{head.seedTxIn}
63-
</a>
64+
{head.seedTxIn && (
65+
<a
66+
href={explorer.tx(head.seedTxIn)}
67+
target="_blank"
68+
className="text-blue-300 hover:text-blue-500"
69+
>
70+
{head.seedTxIn}
71+
</a>
72+
)}
6473
</p>
6574
</div>
6675
<div className="border p-4">
@@ -86,7 +95,7 @@ const HeadDetails: React.FC<HeadDetailsProps> = ({ head, onClose }) => {
8695
<div className="border p-4">
8796
<h3 className="text-lg font-semibold mb-2">Point</h3>
8897
<p>
89-
Block Hash: <a href={`https://sancho.cexplorer.io/block/${head.point.blockHash}`} target="_blank" className="text-blue-300 hover:text-blue-500">
98+
Block Hash: <a href={explorer.block(head.point.blockHash)} target="_blank" className="text-blue-300 hover:text-blue-500">
9099
{head.point.blockHash}
91100
</a> <br />
92101
Slot: {head.point.slot}

hydra-explorer/web/src/components/HeadsTable/index.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { HeadState } from "@/app/model"
55
import { useHeadsData } from "@/providers/HeadsDataProvider"
66
import HeadDetails from "../HeadDetails"
77
import { totalLovelaceValueLocked } from '@/utils'
8+
import { useCardanoExplorer } from '@/providers/CardanoExplorer'
89

910
const HeadsTable: React.FC = () => {
1011
const { heads, error } = useHeadsData()
@@ -14,6 +15,8 @@ const HeadsTable: React.FC = () => {
1415
setSelectedHead(head)
1516
}
1617

18+
const explorer = useCardanoExplorer()
19+
1720
return (
1821
<div className="container mx-auto mt-12 overflow-y-auto">
1922
{error ? (
@@ -36,15 +39,15 @@ const HeadsTable: React.FC = () => {
3639
{heads?.sort((a, b) => b.blockNo - a.blockNo).map((head, index) => (
3740
<tr key={index} className={`${index % 2 === 0 ? 'bg-gray-700' : 'bg-gray-600'}`}>
3841
<td className="truncate text-center border px-4 py-2">
39-
<a href={`https://sancho.cexplorer.io/policy/${head.headId}/mint`} target="_blank" className="text-blue-300 hover:text-blue-500">
42+
<a href={explorer.mintPolicy(head.headId)} target="_blank" className="text-blue-300 hover:text-blue-500">
4043
{head.headId}
4144
</a>
4245
</td>
4346
<td className="truncate text-center border px-4 py-2">{head.status}</td>
4447
<td className="truncate text-center border px-4 py-2">{head.point.slot}</td>
4548
<td className="truncate text-center border px-4 py-2">{head.blockNo}</td>
4649
<td className="truncate text-center border px-4 py-2">
47-
<a href={`https://sancho.cexplorer.io/block/${head.point.blockHash}`} target="_blank" className="text-blue-300 hover:text-blue-500">
50+
<a href={explorer.block(head.point.blockHash)} target="_blank" className="text-blue-300 hover:text-blue-500">
4851
{head.point.blockHash}
4952
</a>
5053
</td>

hydra-explorer/web/src/components/MemberCommitDetails/index.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import React, { useEffect } from 'react'
44
import { HeadMember } from '@/app/model'
5+
import { useCardanoExplorer } from '@/providers/CardanoExplorer'
56

67
interface MemberCommitDetailsProps {
78
member: HeadMember
@@ -23,6 +24,8 @@ const MemberCommitDetails: React.FC<MemberCommitDetailsProps> = ({ member, onClo
2324
}
2425
}, [onClose])
2526

27+
const explorer = useCardanoExplorer()
28+
2629
return (
2730
<div className="fixed inset-0 flex items-center justify-center bg-gray-900 bg-opacity-50 z-50">
2831
<div className="bg-gray-800 p-6 rounded-lg shadow-xl relative">
@@ -50,12 +53,12 @@ const MemberCommitDetails: React.FC<MemberCommitDetailsProps> = ({ member, onClo
5053
return (
5154
<tr key={index} className={`${index % 2 === 0 ? 'bg-gray-700' : 'bg-gray-600'}`}>
5255
<td className="truncate text-center border px-4 py-2">
53-
<a href={`https://sancho.cexplorer.io/tx/${txId}`} target="_blank" className="text-blue-300 hover:text-blue-500">
56+
<a href={explorer.tx(txId)} target="_blank" className="text-blue-300 hover:text-blue-500">
5457
{txId}
5558
</a>#{txIx}
5659
</td>
5760
<td className="truncate text-center border px-4 py-2">
58-
<a href={`https://sancho.cexplorer.io/address/${commit.address}`} target="_blank" className="text-blue-300 hover:text-blue-500">
61+
<a href={explorer.address(commit.address)} target="_blank" className="text-blue-300 hover:text-blue-500">
5962
{commit.address}
6063
</a>
6164
</td>

hydra-explorer/web/src/components/TickBox/index.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { TickState } from "@/app/model"
44
import useDataFetcher from "@/hooks/DataFetcher"
5+
import { useCardanoExplorer } from "@/providers/CardanoExplorer"
56
import { useState } from "react"
67

78
const TickBox = () => {
@@ -14,6 +15,8 @@ const TickBox = () => {
1415
setError,
1516
})
1617

18+
const explorer = useCardanoExplorer()
19+
1720
return (
1821
<div className="container mx-auto mt-8">
1922
{error ? (
@@ -33,7 +36,7 @@ const TickBox = () => {
3336
<tr>
3437
<td className="truncate text-center border px-4 py-2">{tick?.blockNo}</td>
3538
<td className="truncate text-center border px-4 py-2">
36-
<a href={`https://sancho.cexplorer.io/block/${tick?.point.blockHash}`} target="_blank" className="text-blue-300 hover:text-blue-500">
39+
<a href={explorer.block(tick?.point.blockHash)} target="_blank" className="text-blue-300 hover:text-blue-500">
3740
{tick?.point.blockHash}
3841
</a>
3942
</td>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"use client" // This is a client component 👈🏽
2+
3+
import React, { PropsWithChildren, useContext } from "react"
4+
5+
export interface CardanoExplorer {
6+
mintPolicy: (policyId: string) => string
7+
tx: (txIn: string) => string
8+
block: (blockHash: string) => string
9+
address: (addr: string) => string
10+
}
11+
12+
const CardanoExplorerContext: React.Context<CardanoExplorer> =
13+
React.createContext({} as CardanoExplorer)
14+
15+
export const useCardanoExplorer = () => {
16+
const context = useContext(CardanoExplorerContext)
17+
if (!context) {
18+
throw new Error("useCardanoExplorer must be used within a CardanoExplorerProvider")
19+
}
20+
return context
21+
}
22+
23+
export type CardanoExplorerProps = {
24+
network: string
25+
}
26+
27+
export const CardanoExplorerProvider: React.FC<PropsWithChildren<CardanoExplorerProps>> =
28+
({ network, children }) => {
29+
const cexplorer: CardanoExplorer = {
30+
mintPolicy: (policyId: string) => `https://${network}.cexplorer.io/policy/${policyId}/mint`,
31+
tx: (txIn: string) => `https://${network}.cexplorer.io/tx/${txIn}`,
32+
block: (blockHash: string) => `https://${network}.cexplorer.io/block/${blockHash}`,
33+
address: (addr: string) => `https://${network}.cexplorer.io/address/${addr}`
34+
}
35+
36+
return (
37+
<CardanoExplorerContext.Provider value={cexplorer}>
38+
{children}
39+
</CardanoExplorerContext.Provider>
40+
)
41+
}

hydra-explorer/web/src/providers/HeadsDataProvider/index.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ export interface HeadsDataService {
1212
const HeadsDataContext: React.Context<HeadsDataService> =
1313
React.createContext({} as HeadsDataService)
1414

15-
export const useHeadsDataContext = () => useContext(HeadsDataContext)
15+
export const useHeadsDataContext = () => {
16+
const context = useContext(HeadsDataContext)
17+
if (!context) {
18+
throw new Error("useHeadsDataContext must be used within a HeadsDataProvider")
19+
}
20+
return context
21+
}
1622

1723
export const HeadsDataProvider: React.FC<any> = ({
1824
children

hydra-explorer/web/src/providers/IntervalProvider/index.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ export interface IntervalSettingService {
1212
const IntervalContext: React.Context<IntervalSettingService> =
1313
React.createContext({} as IntervalSettingService)
1414

15-
export const useIntervalContext = () => useContext(IntervalContext)
15+
export const useIntervalContext = () => {
16+
const context = useContext(IntervalContext)
17+
if (!context) {
18+
throw new Error("useIntervalContext must be used within a IntervalSettingProvider")
19+
}
20+
return context
21+
}
1622

1723
const IntervalSettingProvider: React.FC<any> = ({
1824
children

hydra-explorer/web/src/utils.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { HeadState } from "./app/model"
22

33
export const totalLovelaceValueLocked = (head: HeadState) => {
4+
if (head.status == "Finalized" || head.status == "Aborted" ) return 0
45
return (head.members || []).reduce((total, member) => {
56
if (member.commits && Object.keys(member.commits).length > 0) {
6-
return total + Object.values(member.commits).reduce((memberTotal, commit) => {
7+
const memberTotal = Object.values(member.commits).reduce((memberTotal, commit) => {
78
return memberTotal + commit.value.lovelace
89
}, 0)
10+
return total + memberTotal
911
}
1012
return total
1113
}, 0)
12-
}
14+
}

0 commit comments

Comments
 (0)