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
5 changes: 4 additions & 1 deletion .env.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=GA_TEST_1234567890
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=TEST_1234567890
ENVIRONMENT=localhost
ENVIRONMENT=localhost

#
ALCHEMY_API_KEY=test
76 changes: 76 additions & 0 deletions app/api/balances/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { NextRequest, NextResponse } from 'next/server';

const ALCHEMY_API_KEY = process.env.ALCHEMY_API_KEY;
const ALCHEMY_URLS = {
'1': `https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`,
'8453': `https://base-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`,
};

type TokenBalance = {
contractAddress: string;
tokenBalance: string;
};

export async function GET(req: NextRequest) {
const searchParams = req.nextUrl.searchParams;
const address = searchParams.get('address');
const chainId = searchParams.get('chainId');

if (!address || !chainId) {
return NextResponse.json({ error: 'Missing address or chainId' }, { status: 400 });
}

try {
const alchemyUrl = ALCHEMY_URLS[chainId as keyof typeof ALCHEMY_URLS];
if (!alchemyUrl) {
throw new Error(`Chain ${chainId} not supported`);
}

// Get token balances
const balancesResponse = await fetch(alchemyUrl, {
method: 'POST',
headers: {
accept: 'application/json',
'content-type': 'application/json',
},
body: JSON.stringify({
id: 1,
jsonrpc: '2.0',
method: 'alchemy_getTokenBalances',
params: [address],
}),
});

if (!balancesResponse.ok) {
throw new Error(`HTTP error! status: ${balancesResponse.status}`);
}

const balancesData = (await balancesResponse.json()) as {
id: number;
jsonrpc: string;
result: {
tokenBalances: TokenBalance[];
};
};

const nonZeroBalances: TokenBalance[] = balancesData.result.tokenBalances.filter(
(token: TokenBalance) =>
token.tokenBalance !== '0x0000000000000000000000000000000000000000000000000000000000000000',
);

// Filter out failed metadata requests
const tokens = nonZeroBalances
.filter((token) => token !== null)
.map((token) => ({
address: token.contractAddress.toLowerCase(),
balance: BigInt(token.tokenBalance).toString(10),
}));

return NextResponse.json({
tokens,
});
} catch (error) {
console.error('Failed to fetch balances:', error);
return NextResponse.json({ error: 'Failed to fetch balances' }, { status: 500 });
}
}
1 change: 1 addition & 0 deletions app/history/components/HistoryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export function HistoryTable({ history }: HistoryTableProps) {
<div className="flex justify-center font-monospace text-xs">
<Link
href={`/market/${tx.data.market.morphoBlue.chain.id}/${tx.data.market.uniqueKey}`}
className="text-xs"
>
<p>{tx.data.market.uniqueKey.slice(2, 8)} </p>
<p className="opacity-0 group-hover:opacity-100">
Expand Down
2 changes: 1 addition & 1 deletion app/home/_components/HomeHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styles from './Home.module.css';

export default function HomeHeader() {
return (
<div className={styles.HomeHeader}>
<div className={`${styles.HomeHeader} font-zen`}>
<Header />
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions app/info/components/info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function InfoPage() {

const renderImage = (section: (typeof sections)[0], index: number) => (
<div
className={`flex items-center justify-center overflow-hidden rounded-lg ${
className={`flex items-center justify-center overflow-hidden rounded ${
index === sections.length - 1
? 'h-32 w-32 p-2 sm:h-48 sm:w-48 sm:p-4'
: 'h-48 w-full sm:h-64'
Expand All @@ -88,7 +88,7 @@ function InfoPage() {
width={index === sections.length - 1 ? 128 : 800}
height={index === sections.length - 1 ? 128 : 256}
objectFit="contain"
className="rounded-lg"
className="rounded"
/>
</div>
);
Expand All @@ -108,7 +108,7 @@ function InfoPage() {
>
{sections.map((section, index) => (
<div key={`section-${index}`} className="w-full flex-shrink-0 px-4 md:px-8 lg:px-16">
<div className="bg-surface mx-auto max-w-3xl rounded-lg px-4 py-6 shadow-lg sm:px-8 sm:py-8 md:px-12">
<div className="bg-surface mx-auto max-w-3xl rounded px-4 py-6 shadow-lg sm:px-8 sm:py-8 md:px-12">
<h1 className="mb-2 text-center text-3xl font-bold sm:text-4xl">
{section.mainTitle}
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/info/components/sectionData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import vaultsImage from '../../../src/imgs/intro/vaults.png';

function Card({ title, items }: { title: string; items: string[] }) {
return (
<div className="bg-main flex-1 rounded-lg p-4 shadow">
<div className="bg-main flex-1 rounded p-4 shadow">
<h3 className="mb-2 font-zen text-lg font-bold">{title}</h3>
<ul className="list-inside list-disc">
{items.map((item, index) => (
Expand Down
89 changes: 38 additions & 51 deletions app/markets/components/OracleFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,16 @@ type OracleFilterProps = {
export default function OracleFilter({ selectedOracles, setSelectedOracles }: OracleFilterProps) {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const mounted = useRef(true);

useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
mounted.current &&
dropdownRef.current &&
!dropdownRef.current.contains(event.target as Node)
) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => {
mounted.current = false;
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
Expand All @@ -43,16 +37,11 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or
}
};

const clearSelection = () => {
setSelectedOracles([]);
setIsOpen(false);
};

return (
<div className="relative w-full" ref={dropdownRef}>
<div
className={`bg-surface min-w-48 cursor-pointer rounded-sm p-2 shadow-sm transition-colors duration-200 hover:bg-gray-200 dark:hover:bg-gray-700 ${
isOpen ? 'bg-surface-dark' : ''
className={`bg-surface min-w-48 cursor-pointer rounded p-2 shadow-sm transition-all duration-200 hover:bg-gray-200 dark:hover:bg-gray-700 ${
isOpen ? 'bg-gray-200 dark:bg-gray-700' : ''
}`}
role="button"
tabIndex={0}
Expand Down Expand Up @@ -88,44 +77,42 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or
</span>
</div>
</div>
{isOpen && (
<div className="bg-surface absolute z-10 mt-1 w-full rounded-sm shadow-lg">
<ul className="custom-scrollbar max-h-60 overflow-auto pb-12" role="listbox">
{Object.values(OracleVendors).map((oracle) => (
<li
key={oracle}
className={`m-2 flex cursor-pointer items-center justify-between rounded-md p-2 text-sm hover:bg-gray-300 dark:hover:bg-gray-700 ${
selectedOracles.includes(oracle) ? 'bg-gray-300 dark:bg-gray-700' : ''
}`}
onClick={() => toggleOracle(oracle)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
toggleOracle(oracle);
}
}}
role="option"
aria-selected={selectedOracles.includes(oracle)}
tabIndex={0}
>
<span>{oracle}</span>
{OracleVendorIcons[oracle] && (
<Image src={OracleVendorIcons[oracle]} alt={oracle} width={18} height={18} />
)}
</li>
))}
</ul>
<div className="bg-surface absolute bottom-0 left-0 right-0 border-gray-700 p-2">
<button
className="hover:bg-main flex w-full items-center justify-between rounded-sm p-2 text-left text-xs text-secondary"
onClick={clearSelection}
type="button"
<div
className={`bg-surface absolute z-10 mt-1 w-full transform rounded shadow-lg transition-all duration-200 ${
isOpen ? 'visible translate-y-0 opacity-100' : 'invisible -translate-y-2 opacity-0'
}`}
>
<ul className="custom-scrollbar max-h-60 overflow-auto" role="listbox">
{Object.values(OracleVendors).map((oracle) => (
<li
key={oracle}
className={`m-2 flex cursor-pointer items-center justify-between rounded p-2 text-sm transition-colors duration-200 hover:bg-gray-300 dark:hover:bg-gray-700 ${
selectedOracles.includes(oracle) ? 'bg-gray-300 dark:bg-gray-700' : ''
}`}
onClick={() => toggleOracle(oracle)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
toggleOracle(oracle);
}
}}
role="option"
aria-selected={selectedOracles.includes(oracle)}
tabIndex={0}
>
<span>Clear All</span>
<ChevronDownIcon className="h-5 w-5 rotate-180" />
</button>
</div>
</div>
)}
<div className="flex items-center gap-2">
<Image
src={OracleVendorIcons[oracle]}
alt={oracle}
width={16}
height={16}
className="rounded-full"
/>
<span>{oracle}</span>
</div>
</li>
))}
</ul>
</div>
</div>
);
}
8 changes: 4 additions & 4 deletions app/markets/components/markets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,13 @@ export default function Markets() {
/>
</div>

<div className="mt-4 lg:mt-0 flex gap-2">
<div className="mt-4 flex gap-2 lg:mt-0">
<button
onClick={handleRefresh}
type="button"
disabled={loading || isRefetching}
className={`flex items-center gap-2 rounded-md bg-gray-200 p-2 px-3 text-sm text-secondary transition-colors hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 ${
loading || isRefetching ? 'opacity-50 cursor-not-allowed' : ''
className={`flex items-center gap-2 rounded bg-gray-200 p-2 px-3 text-sm text-secondary transition-colors hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 ${
loading || isRefetching ? 'cursor-not-allowed opacity-50' : ''
}`}
>
<FaSync className={`${loading || isRefetching ? 'animate-spin' : ''}`} size={10} />
Expand All @@ -357,7 +357,7 @@ export default function Markets() {
type="button"
aria-expanded={showAdvancedSettings}
aria-controls="advanced-settings-panel"
className="flex items-center gap-2 rounded-md bg-gray-200 p-2 px-3 text-sm text-secondary transition-colors hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600"
className="flex items-center gap-2 rounded bg-gray-200 p-2 px-3 text-sm text-secondary transition-colors hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600"
>
<FaEllipsisH size={16} className={showAdvancedSettings ? 'rotate-180' : ''} />
Advanced
Expand Down
6 changes: 6 additions & 0 deletions app/positions/components/FromAndToMarkets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ export function FromAndToMarkets({
value={fromFilter}
onChange={(e) => onFromFilterChange(e.target.value)}
className="mb-2"
classNames={{
inputWrapper: 'rounded',
}}
/>
<div className="relative min-h-[250px] w-full overflow-x-auto">
{fromMarkets.length === 0 ? (
Expand Down Expand Up @@ -216,6 +219,9 @@ export function FromAndToMarkets({
value={toFilter}
onChange={(e) => onToFilterChange(e.target.value)}
className="mb-2"
classNames={{
inputWrapper: 'rounded',
}}
/>
<div className="relative min-h-[250px] w-full overflow-x-auto">
{toMarkets.length === 0 ? (
Expand Down
Loading