Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/kleros-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/components/pages/evm/address/displays/AccountDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type React from "react";
import { useCallback, useMemo, useState } from "react";
import { getNetworkById } from "../../../../../config/networks";
import type { KlerosTag } from "../../../../../services/KlerosService";
import type { Address, ENSReverseResult, RPCMetadata, Transaction } from "../../../../../types";
import AIAnalysisPanel from "../../../../common/AIAnalysis/AIAnalysisPanel";
import { AddressHeader, TransactionHistory } from "../shared";
Expand All @@ -18,6 +19,7 @@ interface AccountDisplayProps {
ensName?: string | null;
reverseResult?: ENSReverseResult | null;
isMainnet?: boolean;
klerosTag?: KlerosTag | null;
}

const AccountDisplay: React.FC<AccountDisplayProps> = ({
Expand All @@ -30,6 +32,7 @@ const AccountDisplay: React.FC<AccountDisplayProps> = ({
ensName,
reverseResult,
isMainnet = true,
klerosTag,
}) => {
const network = getNetworkById(networkId);
const networkName = network?.name ?? "Unknown Network";
Expand Down Expand Up @@ -82,6 +85,7 @@ const AccountDisplay: React.FC<AccountDisplayProps> = ({
metadata={metadata}
selectedProvider={selectedProvider}
onProviderSelect={onProviderSelect}
klerosTag={klerosTag}
/>

<div className="address-section-content">
Expand Down
4 changes: 4 additions & 0 deletions src/components/pages/evm/address/displays/ContractDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useContext, useMemo } from "react";
import { getNetworkById } from "../../../../../config/networks";
import { AppContext } from "../../../../../context";
import { useSourcify } from "../../../../../hooks/useSourcify";
import type { KlerosTag } from "../../../../../services/KlerosService";
import type { Address, ENSReverseResult, RPCMetadata } from "../../../../../types";
import AIAnalysisPanel from "../../../../common/AIAnalysis/AIAnalysisPanel";
import { AddressHeader } from "../shared";
Expand All @@ -23,6 +24,7 @@ interface ContractDisplayProps {
ensName?: string | null;
reverseResult?: ENSReverseResult | null;
isMainnet?: boolean;
klerosTag?: KlerosTag | null;
}

const ContractDisplay: React.FC<ContractDisplayProps> = ({
Expand All @@ -35,6 +37,7 @@ const ContractDisplay: React.FC<ContractDisplayProps> = ({
ensName,
reverseResult,
isMainnet = true,
klerosTag,
}) => {
const { jsonFiles } = useContext(AppContext);
const network = getNetworkById(networkId);
Expand Down Expand Up @@ -126,6 +129,7 @@ const ContractDisplay: React.FC<ContractDisplayProps> = ({
metadata={metadata}
selectedProvider={selectedProvider}
onProviderSelect={onProviderSelect}
klerosTag={klerosTag}
/>

<div className="address-section-content">
Expand Down
4 changes: 4 additions & 0 deletions src/components/pages/evm/address/displays/ERC1155Display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getAssetUrl,
type TokenMetadata,
} from "../../../../../services/MetadataService";
import type { KlerosTag } from "../../../../../services/KlerosService";
import type { Address, ENSReverseResult, RPCMetadata } from "../../../../../types";
import { decodeAbiString } from "../../../../../utils/hexUtils";
import { logger } from "../../../../../utils/logger";
Expand All @@ -29,6 +30,7 @@ interface ERC1155DisplayProps {
ensName?: string | null;
reverseResult?: ENSReverseResult | null;
isMainnet?: boolean;
klerosTag?: KlerosTag | null;
}

const ERC1155Display: React.FC<ERC1155DisplayProps> = ({
Expand All @@ -41,6 +43,7 @@ const ERC1155Display: React.FC<ERC1155DisplayProps> = ({
ensName,
reverseResult,
isMainnet = true,
klerosTag,
}) => {
const { jsonFiles, rpcUrls } = useContext(AppContext);
const [tokenMetadata, setTokenMetadata] = useState<TokenMetadata | null>(null);
Expand Down Expand Up @@ -234,6 +237,7 @@ const ERC1155Display: React.FC<ERC1155DisplayProps> = ({
onProviderSelect={onProviderSelect}
tokenSymbol={collectionSymbol}
tokenName={collectionName}
klerosTag={klerosTag}
/>

<div className="address-section-content">
Expand Down
4 changes: 4 additions & 0 deletions src/components/pages/evm/address/displays/ERC20Display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getAssetUrl,
type TokenMetadata,
} from "../../../../../services/MetadataService";
import type { KlerosTag } from "../../../../../services/KlerosService";
import type { Address, ENSReverseResult, RPCMetadata } from "../../../../../types";
import { hexToUtf8 } from "../../../../../utils/erc20Utils";
import { logger } from "../../../../../utils/logger";
Expand All @@ -29,6 +30,7 @@ interface ERC20DisplayProps {
ensName?: string | null;
reverseResult?: ENSReverseResult | null;
isMainnet?: boolean;
klerosTag?: KlerosTag | null;
}

const ERC20Display: React.FC<ERC20DisplayProps> = ({
Expand All @@ -41,6 +43,7 @@ const ERC20Display: React.FC<ERC20DisplayProps> = ({
ensName,
reverseResult,
isMainnet = true,
klerosTag,
}) => {
const { jsonFiles, rpcUrls } = useContext(AppContext);
const [tokenMetadata, setTokenMetadata] = useState<TokenMetadata | null>(null);
Expand Down Expand Up @@ -247,6 +250,7 @@ const ERC20Display: React.FC<ERC20DisplayProps> = ({
onProviderSelect={onProviderSelect}
tokenSymbol={tokenSymbol}
tokenName={tokenName}
klerosTag={klerosTag}
/>

<div className="address-section-content">
Expand Down
4 changes: 4 additions & 0 deletions src/components/pages/evm/address/displays/ERC721Display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getAssetUrl,
type TokenMetadata,
} from "../../../../../services/MetadataService";
import type { KlerosTag } from "../../../../../services/KlerosService";
import type { Address, ENSReverseResult, RPCMetadata } from "../../../../../types";
import { decodeAbiString } from "../../../../../utils/hexUtils";
import { logger } from "../../../../../utils/logger";
Expand All @@ -29,6 +30,7 @@ interface ERC721DisplayProps {
ensName?: string | null;
reverseResult?: ENSReverseResult | null;
isMainnet?: boolean;
klerosTag?: KlerosTag | null;
}

const ERC721Display: React.FC<ERC721DisplayProps> = ({
Expand All @@ -41,6 +43,7 @@ const ERC721Display: React.FC<ERC721DisplayProps> = ({
ensName,
reverseResult,
isMainnet = true,
klerosTag,
}) => {
const { jsonFiles, rpcUrls } = useContext(AppContext);
const [tokenMetadata, setTokenMetadata] = useState<TokenMetadata | null>(null);
Expand Down Expand Up @@ -216,6 +219,7 @@ const ERC721Display: React.FC<ERC721DisplayProps> = ({
onProviderSelect={onProviderSelect}
tokenSymbol={collectionSymbol}
tokenName={collectionName}
klerosTag={klerosTag}
/>

<div className="address-section-content">
Expand Down
4 changes: 4 additions & 0 deletions src/components/pages/evm/address/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useLocation, useParams } from "react-router-dom";
import { AppContext } from "../../../../context";
import { useDataService } from "../../../../hooks/useDataService";
import { useENS } from "../../../../hooks/useENS";
import { useKlerosTag } from "../../../../hooks/useKlerosTag";
import { useProviderSelection } from "../../../../hooks/useProviderSelection";
import { ENSService } from "../../../../services/ENS/ENSService";
import type { Address as AddressData, AddressType, DataWithMetadata } from "../../../../types";
Expand Down Expand Up @@ -60,6 +61,8 @@ export default function Address() {
`address_${numericNetworkId}_${address}`,
);

const klerosTag = useKlerosTag(address, numericNetworkId);

// Resolve ENS name to address
useEffect(() => {
if (!isEnsName || !addressParam) {
Expand Down Expand Up @@ -250,6 +253,7 @@ export default function Address() {
metadata: addressDataResult?.metadata,
selectedProvider,
onProviderSelect: setSelectedProvider,
klerosTag,
};

// Render appropriate display component based on detected type
Expand Down
21 changes: 21 additions & 0 deletions src/components/pages/evm/address/shared/AddressHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type React from "react";
import { useTranslation } from "react-i18next";
import { getKlerosCurateItemUrl, type KlerosTag } from "../../../../../services/KlerosService";
import type { AddressType, RPCMetadata } from "../../../../../types";
import { getAddressTypeIcon, getAddressTypeLabel } from "../../../../../utils/addressTypeDetection";
import { RPCIndicator } from "../../../../common/RPCIndicator";
Expand All @@ -12,6 +14,7 @@ interface AddressHeaderProps {
onProviderSelect?: (provider: string) => void;
tokenSymbol?: string;
tokenName?: string;
klerosTag?: KlerosTag | null;
}

// Truncate hash to show first and last N characters
Expand All @@ -31,7 +34,9 @@ const AddressHeader: React.FC<AddressHeaderProps> = ({
onProviderSelect,
tokenSymbol,
tokenName,
klerosTag,
}) => {
const { t } = useTranslation("address");
const truncatedHash = truncateHash(addressHash, 4);

return (
Expand All @@ -41,6 +46,22 @@ const AddressHeader: React.FC<AddressHeaderProps> = ({
<span className="address-type-icon">{getAddressTypeIcon(addressType)}</span>
<span className="address-type-label">{getAddressTypeLabel(addressType)}</span>
{tokenSymbol && <span className="address-token-symbol">{tokenSymbol}</span>}
{klerosTag && (
<a
href={getKlerosCurateItemUrl(klerosTag.itemID)}
target="_blank"
rel="noopener noreferrer"
className="kleros-verified-tag"
title={t("klerosVerifiedTooltip")}
>
<img
src={`${import.meta.env.BASE_URL}kleros-logo.png`}
alt="Kleros"
className="kleros-logo"
/>
{klerosTag.publicNameTag} ↗
</a>
)}
</div>
{(ensName || tokenName) && <span className="address-ens-name">{ensName || tokenName}</span>}
<span className="tx-mono header-subtitle hide-mobile">{addressHash}</span>
Expand Down
2 changes: 1 addition & 1 deletion src/components/pages/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default function Home() {
const [showTestnets, setShowTestnets] = useState(false);

const { productionNetworks, testnetNetworks } = useMemo(() => {
const isDevelopment = process.env.REACT_APP_ENVIRONMENT === "development";
const isDevelopment = import.meta.env.VITE_ENVIRONMENT === "development";
const localhostChainId = 31337;

// In development, treat localhost as a production network (show with other networks)
Expand Down
4 changes: 2 additions & 2 deletions src/config/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ export function getEnabledNetworks(): NetworkConfig[] {
const envNetworks = process.env.REACT_APP_OPENSCAN_NETWORKS;
const localhostChainId = 31337;

// REACT_APP_ENVIRONMENT is set by webpack DefinePlugin based on NODE_ENV
const isDevelopment = process.env.REACT_APP_ENVIRONMENT === "development";
// VITE_ENVIRONMENT is injected via vite.config.ts define block based on NODE_ENV
const isDevelopment = import.meta.env.VITE_ENVIRONMENT === "development";

// Check if localhost is explicitly enabled in REACT_APP_OPENSCAN_NETWORKS
const isLocalhostExplicitlyEnabled = envNetworks
Expand Down
2 changes: 1 addition & 1 deletion src/config/subdomains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface SubdomainConfig {
const WEENUS_SEPOLIA_ADDRESS = "0x7E0987E5b3a30e3f2828572Bb659A548460a3003";

// Check if we're in development mode
const isDevelopment = process.env.REACT_APP_ENVIRONMENT === "development";
const isDevelopment = import.meta.env.VITE_ENVIRONMENT === "development";

export const subdomainConfig: SubdomainConfig[] = [
// Network subdomains
Expand Down
2 changes: 1 addition & 1 deletion src/context/AppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const AppContextProvider = ({ children }: { children: ReactNode }) => {

// Check if Hardhat should be included (only when both conditions are met)
const envNetworks = process.env.REACT_APP_OPENSCAN_NETWORKS;
const isDevelopment = process.env.REACT_APP_ENVIRONMENT === "development";
const isDevelopment = import.meta.env.VITE_ENVIRONMENT === "development";
const hardhatInEnv = envNetworks?.split(",").some((id) => id.trim() === "31337");

// Add Hardhat network if in development AND explicitly enabled
Expand Down
40 changes: 40 additions & 0 deletions src/hooks/useKlerosTag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useEffect, useState } from "react";
import { fetchAddress } from "../services/MetadataService";
import { type KlerosTag, fetchKlerosTag, isKlerosGraphEnabled } from "../services/KlerosService";

export function useKlerosTag(
address: string | null | undefined,
chainId: number,
): KlerosTag | null {
const [tag, setTag] = useState<KlerosTag | null>(null);

useEffect(() => {
if (!address || chainId !== 1) {
setTag(null);
return;
}

setTag(null);

if (isKlerosGraphEnabled()) {
fetchKlerosTag(address)
.then(setTag)
.catch(() => {
// Fallback to metadata service on Graph error
fetchAddress(chainId, address).then((meta) => {
if (meta?.source?.[0] === "kleros" && meta.label) {
setTag({ itemID: "", publicNameTag: meta.label });
}
});
});
} else {
fetchAddress(chainId, address).then((meta) => {
if (meta?.source?.[0] === "kleros" && meta.label) {
setTag({ itemID: "", publicNameTag: meta.label });
}
});
}
}, [address, chainId]);

return tag;
}
1 change: 1 addition & 0 deletions src/locales/en/address.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"klerosVerifiedTooltip": "Verified by Kleros curated registry",
"balance": "Balance",
"contractName": "Contract Name",
"compiler": "Compiler",
Expand Down
1 change: 1 addition & 0 deletions src/locales/es/address.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"klerosVerifiedTooltip": "Verificado por el registro curado de Kleros",
"balance": "Balance",
"contractName": "Nombre del contrato",
"compiler": "Compilador",
Expand Down
Loading
Loading