Skip to content

Commit

Permalink
sync: merkl app changes (#46)
Browse files Browse the repository at this point in the history
* fix: some type errors

* add: services model draft

* change: more opportunity types

* fix: lint

* add: themes and theme switcher in dev mode (#4)

* add: theme selector when in dev mode

* add: theme switcher in dev mode

* fix: protocol empty tag

* fix: lint error

* Tabs sync (#5)

* tabs, capitalize, socials

* fix lint

* change links to terms & priuvacy

* lint

* move edit address to breadcrumbs

* user edit in component

* footer issue ok

* show bg-main color instead of banner outside of home and opportunities

* add link to protocol header

* implement zkSync colors/fonts as default

* commit hash

* lint

* remove comments

* lint

* feat: re add CI (#6)

* Feat/leaderboard display (#7)

* Update the display of daily rewards

* refactor: update CampaignTableRow to use Dropdown for blacklist and whitelist, and improve layout with Divider

* wip handling rewards

* update: dashboard styling (#8)

* tweak: dashboard

* tweak: dappkit

* fix: no user warning

* remove: input from description

* fix: lint

* add(front): modal, hero, select, tabs/tags, pagination (#9)

* pagination wip

* review Hero cpt
gp

* change pagination

* change modal

* change Hero + connect wallet and search results modals

* lint

* commit hash

* comit hash

* commit

* update: opportunity campaigns/leaderboard view (#11)

* update: campaign information collapsible

* update: campaign information

* add: campaign rules

* update: leaderboard

* fixes

* fix: lint

* tweaks

* fix: aggregate

* feat: add APR modal and table components for opportunity details on h… (#10)

* feat: add APR modal and table components for opportunity details on hover opportunities table

* lint

* Apr tvl modal end

* Feat Hero campaign and protocol (#13)

* Feat Hero campaign and protocol

* fix api call on subpage

* lint and request can't be undefinable on service

* feat(opportunity): new hero, tableRow, OpportunityFilters (#15)

* working on table row + new hero image

* add fitlers

* add todos

* lint

* lint

* ✨ sum daily rewards fora  protocol (#16)

* Fix/campaign page (#17)

* wording

* fix hero link default home

* lint

* wording

* wording

* show icon

* ✨ redirect to Etherscan on TOken tooltip

* 🐛 change Time zone UTC

* update: opportunities pages (#14)

* add: metrics badges

* update: opportunity list

* fix: rewardsRecord sometimes being missing

* add: apply button

* add: loading bar

* rm: log & lint

* add: protocols filter

* fix: search params

* fix:

* fix: lint

* add: missing chains

* fixes

* update: dappkit

* fix: lint

* remove: comment

* add: constant

* apr (#18)

* apr done

* hide forwards if none + change border

* lint

* replace content null

* Fix/campaign page (#20)

* wording

* fix lint error

* fix time when live

* wording

* link to dashboard on leaderboard addresses

* Leaderboard campaign selector display

* lint

* add lastSnapshot

* add lastSnapshot (#21)

* fixes: feedback, mainly opportunities & dashboard (#22)

* fix: search & filters

* update: descriptions

* add: rewards siorting

* add: tvl filter

* fix

* fix: redirect

* fix: whitelist

* add: selective claim

* add: selective token

* add: global claim

* fix

* lint

* typo

* fix: explorer

* caching

* add caching test

* lint

* update

* add: cache on static resoruces (#23)

* Enhance opportunity data retrieval with APR and daily rewards metrics (#24)

* fix: pagination defaulting  & cache (#25)

* fix: bugs in selectors

* fix: dappkit

* clean wip: comment out static sideDatas for dynamic implementation (#26)

* fix: protocl filter (#27)

* fix: protocol desc (#28)

* fix: protocol: description

* rm: log

* token stats + cleaning (#29)

* Small APR Fix (#19)

* lint

* commit hash

* commit hash

* commit hash

* Fixes on protocol, chain, token and campaign pages (#30)

* Fixes on protocol, chain, token and campaign pages

* lint

* fix tooltip

* add: depositor (#31)

* update: dappkit (#33)

* remove: workflwos

---------

Co-authored-by: sheykei <[email protected]>
Co-authored-by: Viande <[email protected]>
Co-authored-by: Picodes <[email protected]>
Co-authored-by: hugolxt <[email protected]>
Co-authored-by: Hugo Lextrait <[email protected]>
  • Loading branch information
6 people authored Dec 16, 2024
1 parent 1b51273 commit af7653b
Show file tree
Hide file tree
Showing 119 changed files with 3,033 additions and 1,256 deletions.
Binary file modified bun.lockb
Binary file not shown.
118 changes: 75 additions & 43 deletions merkl.config.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,75 @@
import { createColoring } from "dappkit";
import { createConfig } from "src/config/type";
import { createClient, custom, http } from "viem";
import hero from "src/customer/assets/images/hero.jpg?url";
import { http, createClient, custom } from "viem";
import {
mainnet,
optimism,
rootstock,
bsc,
gnosis,
thunderCore,
fuse,
polygon,
manta,
xLayer,
fantom,
fraxtal,
filecoin,
zksync,
worldchain,
arbitrum,
astar,
polygonZkEvm,
coreDao,
moonbeam,
sei,
astarZkEVM,
mantle,
avalanche,
base,
blast,
bob,
bsc,
coreDao,
etherlink,
fantom,
filecoin,
fraxtal,
fuse,
gnosis,
immutableZkEvm,
mode,
arbitrum,
avalanche,
linea,
bob,
blast,
taiko,
lisk,
mainnet,
manta,
mantle,
mode,
moonbeam,
optimism,
polygon,
polygonZkEvm,
rootstock,
scroll,
sei,
taiko,
thunderCore,
worldchain,
xLayer,
zksync,
} from "viem/chains";
import { coinbaseWallet, walletConnect } from "wagmi/connectors";
import hero from "src/customer/assets/images/hero.jpg?url";
import { eip712WalletActions } from "viem/zksync";
import { coinbaseWallet, walletConnect } from "wagmi/connectors";

export default createConfig({
appName: "Merkl",
modes: ["dark"],
defaultTheme: "merkl",
modes: ["dark", "light"],
defaultTheme: "ignite",
deposit: false,
themes: {
ignite: {
base: createColoring(["#1755F4", "#FF7900", "#0D1530"], ["#1755F4", "#FF7900", "#FFFFFF"]),
info: createColoring(["#2ABDFF", "#2ABDFF", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
good: createColoring(["#40B66B", "#40B66B", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
warn: createColoring(["#ff9600", "#ff9600", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
harm: createColoring(["#d22e14", "#d22e14", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
},
merkl: {
base: createColoring(["#1F2333", "#B8AAFD", "#131620"], ["#FCF8F5", "#B8AAFD", "white"]),
base: createColoring(["#1755F4", "#FF7900", "#0D1530"], ["#1755F4", "#FF7900", "#FFFFFF"]),
info: createColoring(["#2ABDFF", "#2ABDFF", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
good: createColoring(["#40B66B", "#40B66B", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
warn: createColoring(["#ff9600", "#ff9600", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
harm: createColoring(["#d22e14", "#d22e14", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
},
backoffice: {
base: createColoring(["#8B8D98", "#9984D2", "#000000"], ["#8B8D98", "#9984D2", "#FFFFFF"]),
info: createColoring(["#2ABDFF", "#2ABDFF", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
good: createColoring(["#40B66B", "#40B66B", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
warn: createColoring(["#ff9600", "#ff9600", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
harm: createColoring(["#d22e14", "#d22e14", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
},
puffer: {
base: createColoring(["#2A35BD", "#3D3D3D", "#0E1035"], ["#2A35BD", "#F5F9FF", "#FFFFFF"]),
info: createColoring(["#2ABDFF", "#2ABDFF", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
good: createColoring(["#40B66B", "#40B66B", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
warn: createColoring(["#ff9600", "#ff9600", "#131620"], ["#FFFFFF", "#40B66B", "white"]),
Expand Down Expand Up @@ -76,16 +100,16 @@ export default createConfig({
// route: "/protocols",
// key: crypto.randomUUID(),
// },
terms: {
icon: "RiCompassesLine",
route: "/terms",
key: crypto.randomUUID(),
},
privacy: {
icon: "RiInformationFill",
route: "/privacy",
key: crypto.randomUUID(),
},
// terms: {
// icon: "RiCompassesLine",
// route: "/terms",
// key: crypto.randomUUID(),
// },
// privacy: {
// icon: "RiInformationFill",
// route: "/privacy",
// key: crypto.randomUUID(),
// },
},
socials: {
discord: "",
Expand All @@ -95,13 +119,17 @@ export default createConfig({
},
links: {
merkl: "https://merkl.xyz/",
merklTermsConditions: "https://app.merkl.xyz/merklTerms.pdf",
merklPrivacy: "https://privacy.angle.money",
},
footerLinks: [],
wagmi: {
chains: [
mainnet,
optimism,
rootstock,
bsc,
lisk,
gnosis,
thunderCore,
fuse,
Expand All @@ -111,6 +139,7 @@ export default createConfig({
fantom,
fraxtal,
filecoin,
etherlink,
zksync,
worldchain,
astar,
Expand All @@ -133,7 +162,10 @@ export default createConfig({
],
client({ chain }) {
if (chain.id === zksync.id)
return createClient({ chain, transport: custom(window.ethereum!) }).extend(eip712WalletActions());
return createClient({
chain,
transport: custom(window.ethereum!),
}).extend(eip712WalletActions());
return createClient({ chain, transport: http() });
},
ssr: true,
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"start": "bun run scripts/start.ts",
"build": "remix vite:build",
"dev": "remix vite:dev --host",
"lint": "biome check --fix ./src",
"lint:ci": "biome check --diagnostic-level error ./src",
"lint": "biome check --fix ./src ./*.ts",
"lint:ci": "biome check --diagnostic-level error ./src ./*.ts",
"serve": "remix-serve ./build/server/index.js",
"typecheck": "tsc"
},
Expand All @@ -17,10 +17,10 @@
],
"dependencies": {
"@acab/ecsstatic": "^0.8.0",
"@merkl/api": "0.10.96",
"@ariakit/react": "^0.4.12",
"@elysiajs/eden": "^1.1.3",
"@emotion/css": "^11.13.4",
"@merkl/api": "0.10.156",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-scroll-area": "^1.2.0",
"@remix-run/dev": "^2.11.2",
Expand All @@ -39,6 +39,7 @@
"lucide-react": "^0.439.0",
"match-sorter": "^6.3.4",
"moment": "^2.30.1",
"node-cache": "^5.1.2",
"qs": "^6.13.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -48,7 +49,7 @@
"tailwindcss": "^3.4.12",
"tailwindcss-animate": "^1.0.7",
"typedoc": "^0.26.7",
"viem": "2.x",
"viem": "2.21.54",
"vite-plugin-dts": "^4.2.1",
"wagmi": "^2.12.29",
"zustand": "^5.0.0-rc.2"
Expand Down
42 changes: 42 additions & 0 deletions src/api/services/cache.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { ClientLoaderFunction, ClientLoaderFunctionArgs } from "@remix-run/react";
import NodeCache from "node-cache";

export class CacheService {
cache = new NodeCache();

set<T>(key: string, ttl: number, value: T) {
this.cache.set(key, value, ttl);

return value;
}

get<T>(key: string): T | undefined {
const cached = this.cache.get<T>(key);

return cached;
}

reset(key: string) {
this.cache.del(key);
}

wrap(resource: string, ttl: number): ClientLoaderFunction {
const loader = async ({ request, serverLoader }: ClientLoaderFunctionArgs) => {
const key = `${resource}:${request.url}`;
const cache = Cache.get(key);

if (cache) return cache;

const data = await serverLoader();

Cache.set(key, ttl, data);

return data;
};

loader.hydrate = true;
return loader;
}
}

export const Cache = new CacheService();
6 changes: 6 additions & 0 deletions src/api/services/campaigns/campaign.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Campaign as CampaignFromApi } from "@merkl/api";
import type { Fetched } from "src/api/types";

export type Campaign<C extends CampaignFromApi["type"] = CampaignFromApi["type"]> = Fetched<CampaignFromApi<C>> & {
params: CampaignFromApi<C>["params"];
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import type { Campaign } from "@angleprotocol/merkl-api";
import { api } from "../index.server";
import type { Campaign } from "@merkl/api";
import { fetchWithLogs } from "src/api/utils";
import { api } from "../../index.server";

export abstract class CampaignService {
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 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;
}

/**
* Retrieves opportunities query params from page request
* @param request request containing query params such as chains, status, pagination...
Expand Down Expand Up @@ -36,19 +49,18 @@ export abstract class CampaignService {
}

// ------ Fetch all campaigns
static async get(): Promise<Campaign[]> {
static async get() {
const { data } = await api.v4.campaigns.index.get({ query: {} });

return data;
}

static async getByParams(query: Parameters<typeof api.v4.campaigns.index.get>[0]["query"]): Promise<Campaign[]> {
const { data } = await api.v4.campaigns.index.get({ query });
return data;
static async getByParams(query: Parameters<typeof api.v4.campaigns.index.get>[0]["query"]) {
return await CampaignService.#fetch(async () => api.v4.campaigns.index.get({ query }));
}

// ------ Fetch a campaign by ID
static async getByID(Id: string): Promise<Campaign | null> {
static async getByID(_Id: string): Promise<Campaign | null> {
return null;
}
}
6 changes: 6 additions & 0 deletions src/api/services/opportunity/opportunity.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Opportunity as OpportunityFromApi } from "@merkl/api";
import type { Fetched } from "src/api/types";
import type { Campaign } from "../campaigns/campaign.model";

export type Opportunity = Fetched<OpportunityFromApi>;
export type OpportunityWithCampaigns = Fetched<OpportunityFromApi & { campaigns: Campaign[] }>;
Loading

0 comments on commit af7653b

Please sign in to comment.