Skip to content

Commit

Permalink
Add asset icons
Browse files Browse the repository at this point in the history
  • Loading branch information
ifavo committed Nov 29, 2024
1 parent 9c0f2bc commit 27f5712
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 13 deletions.
6 changes: 1 addition & 5 deletions components/allowances/dashboard/cells/AllowanceCell.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { PencilIcon } from '@heroicons/react/24/outline';
import ControlsWrapper from 'components/allowances/controls/ControlsWrapper';
import Button from 'components/common/Button';
import WithHoverTooltip from 'components/common/WithHoverTooltip';
import { useRevoke } from 'lib/hooks/ethereum/useRevoke';
import type { AllowanceData, OnUpdate } from 'lib/interfaces';
import { getAllowanceI18nValues } from 'lib/utils/allowances';
import { SECOND } from 'lib/utils/time';
Expand All @@ -21,9 +17,9 @@ const AllowanceCell = ({ allowance, onUpdate }: Props) => {
const t = useTranslations();
const locale = useLocale();
const [editing, setEditing] = useState<boolean>();
const { update } = useRevoke(allowance, onUpdate);
const { i18nKey, amount, tokenId, symbol } = getAllowanceI18nValues(allowance);


const classes = twMerge(
!allowance.spender && 'text-zinc-500 dark:text-zinc-400',
'flex items-center gap-2',
Expand Down
30 changes: 22 additions & 8 deletions components/allowances/dashboard/cells/AssetCell.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use client';

import ChainOverlayLogo from 'components/common/ChainOverlayLogo';
import Href from 'components/common/Href';
import WithHoverTooltip from 'components/common/WithHoverTooltip';
import type { BaseTokenData } from 'lib/interfaces';
import { getChainExplorerUrl } from 'lib/utils/chains';
import { formatBalance, formatFiatBalance } from 'lib/utils/formatting';
import { useLayoutEffect, useRef, useState } from 'react';
import Image from 'next/image';
import { getVeChainAssetIcon } from 'lib/utils/tokens';

interface Props {
asset: BaseTokenData;
Expand All @@ -15,6 +16,7 @@ interface Props {
const AssetCell = ({ asset }: Props) => {
const ref = useRef(null);
const [showTooltip, setShowTooltip] = useState(false);
const [tokenIcon, setTokenIcon] = useState<string | undefined>(undefined);

// This is pretty hacky, but it works to detect that we're on the address page, so single chain usage
const isOnAddressPage = typeof window !== 'undefined' && window.location.pathname.includes('/address/');
Expand All @@ -25,6 +27,14 @@ const AssetCell = ({ asset }: Props) => {
}
}, [ref]);

useLayoutEffect(() => {
const loadIcon = async () => {
const icon = await getVeChainAssetIcon(asset.contract);
setTokenIcon(icon);
};
loadIcon();
}, [asset.contract]);

const explorerUrl = `${getChainExplorerUrl(asset.chainId)}/account/${asset.contract.address}`;

let link = (
Expand All @@ -44,13 +54,17 @@ const AssetCell = ({ asset }: Props) => {
<div className="flex items-center gap-1 py-1">
<div className="flex flex-col items-start gap-0.5">
<div className="flex items-center gap-2 text-base w-48 lg:w-56">
<ChainOverlayLogo
src={asset.metadata.icon}
alt={asset.metadata.symbol}
chainId={isOnAddressPage ? undefined : asset.chainId}
size={24}
overlaySize={16}
/>
{tokenIcon ? (
<Image
src={tokenIcon}
alt={asset.metadata.symbol}
width={24}
height={24}
className="rounded-full border border-gray-700 dark:border-gray-200"
/>
) : (
<div className="w-6 h-6 bg-gray-200 dark:bg-gray-700 rounded-full border border-gray-700 dark:border-gray-200" />
)}
{link}
</div>

Expand Down
61 changes: 61 additions & 0 deletions lib/utils/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,67 @@ import { deduplicateArray } from '.';
import { withFallback } from './promises';
import { formatFixedPointBigInt } from './formatting';

interface VeChainToken {
name: string;
symbol: string;
decimals: number;
address: string;
desc?: string;
icon?: string;
totalSupply?: string;
}

interface VeChainNFT {
name: string;
symbol: string;
address: string;
desc?: string;
icon?: string;
}

let veChainTokens: VeChainToken[] = [];
let veChainNFTs: VeChainNFT[] = [];
let tokensInitialized = false;
let nftsInitialized = false;

export const initVeChainTokens = async () => {
if (tokensInitialized) return;

try {
const response = await fetch('https://vechain.github.io/token-registry/main.json');
veChainTokens = await response.json();
tokensInitialized = true;
} catch (error) {
console.error('Failed to load VeChain token registry:', error);
}
};

export const initVeChainNFTs = async () => {
if (nftsInitialized) return;

try {
const response = await fetch('https://vechain.github.io/nft-registry/main.json');
veChainNFTs = await response.json();
nftsInitialized = true;
} catch (error) {
console.error('Failed to load VeChain NFT registry:', error);
}
};

export const getVeChainAssetIcon = async (contract: TokenContract): Promise<string | undefined> => {
if (isErc721Contract(contract)) {
await initVeChainNFTs();
const nft = veChainNFTs.find(t => t.address.toLowerCase() === contract.address.toLowerCase());
if (!nft?.icon) return undefined;
return `https://vechain.github.io/nft-registry/${nft.icon}`;
} else {
await initVeChainTokens();
const token = veChainTokens.find(t => t.address.toLowerCase() === contract.address.toLowerCase());
if (!token?.icon) return undefined;
return `https://vechain.github.io/token-registry/assets/${token.icon}`;
}
};

export const isSpamToken = (symbol: string) => {
const spamRegexes = [
// Includes http(s)://
Expand Down
14 changes: 14 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ const nextConfig = {
// Optimize client bundle
removeConsole: process.env.NODE_ENV === 'production',
},
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'vechain.github.io',
pathname: '/token-registry/assets/**',
},
{
protocol: 'https',
hostname: 'vechain.github.io',
pathname: '/nft-registry/assets/**',
},
],
},
modularizeImports: {
'@heroicons/react/24/outline': {
transform: '@heroicons/react/24/outline/{{member}}',
Expand Down

0 comments on commit 27f5712

Please sign in to comment.