Skip to content

Commit

Permalink
Merge pull request #35 from AngleProtocol/complete-rewards
Browse files Browse the repository at this point in the history
various fixes
  • Loading branch information
clmntsnr authored Dec 3, 2024
2 parents ceb90d5 + 4afbfa9 commit 3e6eefc
Show file tree
Hide file tree
Showing 20 changed files with 172 additions and 162 deletions.
7 changes: 4 additions & 3 deletions src/api/services/chain.service.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import type { Chain } from "@merkl/api";
import { api } from "../index.server";
import { fetchWithLogs } from "../utils";

export abstract class ChainService {
static async #fetch<R, T extends { data: R; status: number }>(
static async #fetch<R, T extends { data: R; status: number; response: Response }>(
call: () => Promise<T>,
resource = "Chain",
): Promise<NonNullable<T["data"]>> {
const { data, status } = await call();
const { data, status } = await fetchWithLogs(call);

if (status === 404) throw new Response(`${resource} not found`, { status });
if (status === 500) throw new Response(`${resource} unavailable`, { status });
if (data == null) throw new Response(`${resource} unavailable`, { status });
return data;
}

static async getAll(): Promise<Chain[]> {
static async getAll() {
const chains = await ChainService.#fetch(async () => api.v4.chains.index.get({ query: {} }));

//TODO: add some cache here
Expand Down
5 changes: 3 additions & 2 deletions src/api/services/opportunity.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { Opportunity } from "@merkl/api";
import config from "merkl.config";
import { api } from "../index.server";
import { fetchWithLogs } from "../utils";

export abstract class OpportunityService {
static async #fetch<R, T extends { data: R; status: number }>(
static async #fetch<R, T extends { data: R; status: number; response: Response }>(
call: () => Promise<T>,
resource = "Opportunity",
): Promise<NonNullable<T["data"]>> {
const { data, status } = await call();
const { data, status } = await fetchWithLogs(call);

if (status === 404) throw new Response(`${resource} not found`, { status });
if (status === 500) throw new Response(`${resource} unavailable`, { status });
Expand Down
5 changes: 3 additions & 2 deletions src/api/services/protocol.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { Protocol } from "@merkl/api";
import { api } from "../index.server";
import { fetchWithLogs } from "../utils";

export abstract class ProtocolService {
static async #fetch<R, T extends { data: R; status: number }>(
static async #fetch<R, T extends { data: R; status: number; response: Response }>(
call: () => Promise<T>,
resource = "Protocol",
): Promise<NonNullable<T["data"]>> {
const { data, status } = await call();
const { data, status } = await fetchWithLogs(call);

if (status === 404) throw new Response(`${resource} not found`, { status });
if (status === 500) throw new Response(`${resource} unavailable`, { status });
Expand Down
5 changes: 3 additions & 2 deletions src/api/services/reward.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { Reward } from "@merkl/api";
import { api } from "../index.server";
import { fetchWithLogs } from "../utils";

export abstract class RewardService {
static async #fetch<R, T extends { data: R; status: number }>(
static async #fetch<R, T extends { data: R; status: number; response: Response }>(
call: () => Promise<T>,
resource = "Reward",
): Promise<NonNullable<T["data"]>> {
const { data, status } = await call();
const { data, status } = await fetchWithLogs(call);

if (status === 404) throw new Response(`${resource} not found`, { status });
if (status === 500) throw new Response(`${resource} unavailable`, { status });
Expand Down
5 changes: 3 additions & 2 deletions src/api/services/token.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { Token } from "@merkl/api";
import { api } from "../index.server";
import { fetchWithLogs } from "../utils";

export abstract class TokenService {
static async #fetch<R, T extends { data: R; status: number }>(
static async #fetch<R, T extends { data: R; status: number; response: Response }>(
call: () => Promise<T>,
resource = "Token",
): Promise<NonNullable<T["data"]>> {
const { data, status } = await call();
const { data, status } = await fetchWithLogs(call);

if (status === 404) throw new Response(`${resource} not found`, { status });
if (status === 500) throw new Response(`${resource} unavailable`, { status });
Expand Down
34 changes: 34 additions & 0 deletions src/api/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import chalk from "chalk";

function logStatus(status: number) {
if (status === 200) return chalk.green(`[${status}]`);
if (status < 500) return chalk.yellow(`[${status}]`);
return chalk.red(`[${status}]`);
}

function logPerformance(ms: number) {
if (ms < 100) return chalk.green(`[${Math.round(ms)}ms]`);
if (ms < 500) return chalk.yellow(`[${Math.round(ms)}ms]`);
return chalk.red(`[${Math.round(ms)}ms]`);
}

function logSize(bytes: number) {
const kb = Math.round(bytes / 1000);

return `[${kb}kb]`;
}

export async function fetchWithLogs<R, T extends { data: R; status: number; response: Response }>(
call: () => Promise<T>,
) {
const start = performance.now();
const response = await call();
const end = performance.now() - start;

process.env.NODE_ENV === "development" &&
console.log(
`${logStatus(response.status)}${logPerformance(end)}${logSize(+(response.response.headers.get("content-length") ?? 0))}: ${response.response.url}`,
);

return response;
}
24 changes: 19 additions & 5 deletions src/components/element/Tag.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Opportunity, Token } from "@angleprotocol/merkl-api";
import type { Opportunity, Token } from "@merkl/api";
import type { Chain } from "@merkl/api";
import { Button, Divider, Dropdown, Group, Hash, Icon, PrimitiveTag, Text } from "dappkit";
import type { ButtonProps } from "dappkit";
import { useWalletContext } from "packages/dappkit/src/context/Wallet.context";
import { type Action, actions } from "src/config/actions";
import type { Protocol } from "src/config/protocols";
import { statuses } from "src/config/status";
Expand All @@ -25,6 +26,8 @@ export type TagProps<T extends keyof TagTypes> = ButtonProps & {
};

export default function Tag<T extends keyof TagTypes>({ type, value, ...props }: TagProps<T>) {
const { chains } = useWalletContext();

switch (type) {
case "status": {
const status = statuses[value as TagTypes["status"]] ?? statuses.LIVE;
Expand Down Expand Up @@ -153,10 +156,21 @@ export default function Tag<T extends keyof TagTypes>({ type, value, ...props }:
<Icon remix="RiArrowRightLine" />
{token?.symbol} on Merkl
</Button>
<Button size="xs" look="soft">
<Icon remix="RiArrowRightLine" />
{token?.symbol} on Etherscan
</Button>
{chains
.find(c => c.id === token.chainId)
?.explorers?.map(explorer => {
return (
<Button
key={`${explorer.url}`}
to={`${explorer.url}/token/${token.address}`}
external
size="xs"
look="soft">
<Icon remix="RiArrowRightLine" />
{token?.symbol} on Etherscan
</Button>
);
})}
</Group>
</Group>
}>
Expand Down
26 changes: 1 addition & 25 deletions src/routes/_merkl.(home).tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
import type { MetaFunction } from "@remix-run/node";
import { Outlet } from "@remix-run/react";
import Hero from "src/components/composite/Hero";
import { http, createConfig } from "wagmi";
import { mainnet, sepolia } from "wagmi/chains";
import { coinbaseWallet, walletConnect } from "wagmi/connectors";

export const meta: MetaFunction = () => {
return [{ title: "New Remix App" }, { name: "description", content: "Welcome to Remix!" }];
return [{ title: "Merkl" }];
};

export const config = createConfig({
chains: [mainnet, sepolia],
connectors: [
coinbaseWallet(),
walletConnect({
customStoragePrefix: "wagmi",
projectId: "26c912aadd2132cd869a5edc00aeea0f",
metadata: {
name: "Example",
description: "Example website",
url: "https://example.com",
icons: [],
},
}),
],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
},
});

export default function Index() {
return (
<Hero
Expand Down
6 changes: 5 additions & 1 deletion src/routes/_merkl.chains.$id.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type LoaderFunctionArgs, json } from "@remix-run/node";
import { type LoaderFunctionArgs, type MetaFunction, json } from "@remix-run/node";
import { Outlet, useLoaderData, useRouteError } from "@remix-run/react";
import { Group, Title } from "dappkit";
import { ChainService } from "src/api/services/chain.service";
Expand All @@ -10,6 +10,10 @@ export async function loader({ params: { id } }: LoaderFunctionArgs) {
return json({ chain });
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
return [{ title: `${data?.chain?.name} on Merkl` }];
};

export default function Index() {
const { chain } = useLoaderData<typeof loader>();
const label = chain.name.toLowerCase();
Expand Down
5 changes: 5 additions & 0 deletions src/routes/_merkl.chains.(all).tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { MetaFunction } from "@remix-run/node";
import { Outlet } from "@remix-run/react";
import Hero from "src/components/composite/Hero";

export const meta: MetaFunction = () => {
return [{ title: "Chains on Merkl" }];
};

export default function Index() {
return (
<Hero
Expand Down
2 changes: 1 addition & 1 deletion src/routes/_merkl.opportunities.$chain.$type.$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function loader({ params: { id, type, chain: chainId } }: LoaderFun

export const meta: MetaFunction<typeof loader> = ({ data, error }) => {
if (error) return [{ title: error }];
return [{ title: `${data?.name} on Merkl` }];
return [{ title: `${data?.opportunity.name} on Merkl` }];
};

export type OutletContextOpportunity = {
Expand Down
89 changes: 0 additions & 89 deletions src/routes/_merkl.opportunity.$chain.$type.$id.tsx

This file was deleted.

8 changes: 7 additions & 1 deletion src/routes/_merkl.protocols.$id.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type LoaderFunctionArgs, json } from "@remix-run/node";
import { type LoaderFunctionArgs, type MetaFunction, json } from "@remix-run/node";
import { Outlet, useLoaderData } from "@remix-run/react";
import { ProtocolService } from "src/api/services/protocol.service";
import Hero from "src/components/composite/Hero";
Expand All @@ -9,6 +9,12 @@ export async function loader({ params: { id } }: LoaderFunctionArgs) {
return json({ protocol });
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data?.protocol) return [{ title: "Merkl" }];

return [{ title: `${data?.protocol?.name} on Merkl` }];
};

export default function Index() {
const { protocol } = useLoaderData<typeof loader>();

Expand Down
5 changes: 5 additions & 0 deletions src/routes/_merkl.protocols.(all).tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { MetaFunction } from "@remix-run/node";
import { Outlet } from "@remix-run/react";
import Hero from "src/components/composite/Hero";

export const meta: MetaFunction = () => {
return [{ title: "Protocols on Merkl" }];
};

export default function Index() {
return (
<Hero
Expand Down
10 changes: 9 additions & 1 deletion src/routes/_merkl.status.$status.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type LoaderFunctionArgs, json } from "@remix-run/node";
import { type LoaderFunctionArgs, type MetaFunction, json } from "@remix-run/node";
import { Outlet, useLoaderData } from "@remix-run/react";
import Hero from "src/components/composite/Hero";
import { type Status, getStatus, statuses } from "src/config/status";
Expand All @@ -11,6 +11,14 @@ export async function loader({ params: { status: _status } }: LoaderFunctionArgs
return json({ status });
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data?.status) return [{ title: "Merkl" }];

const status = data.status.charAt(0).toUpperCase() + data.status.slice(1).toLowerCase();

return [{ title: `${status} opportunities on Merkl` }];
};

export default function Index() {
const { status: _status } = useLoaderData<typeof loader>();
const status = statuses[_status as Status];
Expand Down
Loading

0 comments on commit 3e6eefc

Please sign in to comment.