diff --git a/README.md b/README.md index 00ebf2c2..7060e118 100644 --- a/README.md +++ b/README.md @@ -45,11 +45,13 @@ yarn install ENVIRONMENT=development NEXT_PUBLIC_SUPABASE_ANON_KEY= NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co -NEXT_PUBLIC_SLACK_NEW_PROFILE_WEBHOOK= NEXT_PUBLIC_OPENSEA_API_KEYS= -NEXT_PUBLIC_COVALENT_API_KEYS=ckey_xxx,ckey_xxx NEXT_PUBLIC_CMC_PRO_API_KEYS= -NEXT_PUBLIC_REDIS_URL= + +COVALENT_API_KEYS=ckey_xxx,ckey_xxx +SLACK_NEW_PROFILE_WEBHOOK= +SUPABASE_SERVICE_KEY= +REDIS_URL= ``` - Copy `.env.example` inside `@bento/web` to `.env.debug.local`/`.env.development.local` and fill in the contents. diff --git a/packages/bento-common/config/index.ts b/packages/bento-common/config/index.ts index 84f54699..2ba36ce9 100644 --- a/packages/bento-common/config/index.ts +++ b/packages/bento-common/config/index.ts @@ -1,11 +1,8 @@ type EnvironmentSecrets = { SUPABASE_ANON_KEY: string; SUPABASE_URL: string; - SLACK_NEW_PROFILE_WEBHOOK: string; OPENSEA_API_KEYS: string[]; - COVALENT_API_KEYS: string[]; CMC_PRO_API_KEYS: string[]; - REDIS_URL: string; }; const HARDCODED_SECRETS = { @@ -21,17 +18,14 @@ const HARDCODED_SECRETS = { export type Secrets = EnvironmentSecrets & typeof HARDCODED_SECRETS; -const splitAPIKeys = (value: string | undefined) => value?.split(',') || []; +export const splitAPIKeys = (value: string | undefined) => + value?.split(',') || []; export const Config: Secrets = { SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '', SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL || '', - SLACK_NEW_PROFILE_WEBHOOK: - process.env.NEXT_PUBLIC_SLACK_NEW_PROFILE_WEBHOOK || '', OPENSEA_API_KEYS: splitAPIKeys(process.env.NEXT_PUBLIC_OPENSEA_API_KEYS), - COVALENT_API_KEYS: splitAPIKeys(process.env.NEXT_PUBLIC_COVALENT_API_KEYS), CMC_PRO_API_KEYS: splitAPIKeys(process.env.NEXT_PUBLIC_CMC_PRO_API_KEYS), - REDIS_URL: process.env.NEXT_PUBLIC_REDIS_URL || '', ...HARDCODED_SECRETS, }; diff --git a/packages/bento-core/chains/indexers/Covalent.ts b/packages/bento-core/chains/indexers/Covalent.ts index 913d9e3b..d55bc83f 100644 --- a/packages/bento-core/chains/indexers/Covalent.ts +++ b/packages/bento-core/chains/indexers/Covalent.ts @@ -1,4 +1,5 @@ -import { Config, randomOf } from '@bento/common'; +import { splitAPIKeys } from '@bento/common'; +import { randomOf } from '@bento/common'; import axios from 'axios'; type Options = { @@ -10,7 +11,7 @@ export const getTokenBalancesFromCovalent = async ({ chainId, walletAddress, }: Options): Promise => { - const API_KEY = randomOf(Config.COVALENT_API_KEYS); + const API_KEY = randomOf(splitAPIKeys(process.env.COVALENT_API_KEYS)); const API_URL = `https://api.covalenthq.com/v1/${chainId}/address/${walletAddress}/balances_v2/?key=${API_KEY.replace( ':', '', diff --git a/packages/bento-web/.env.example b/packages/bento-web/.env.example index e417bd75..f0f2b971 100644 --- a/packages/bento-web/.env.example +++ b/packages/bento-web/.env.example @@ -1,8 +1,10 @@ ENVIRONMENT=debug NEXT_PUBLIC_SUPABASE_ANON_KEY= NEXT_PUBLIC_SUPABASE_URL=https://*.supabase.co -NEXT_PUBLIC_SLACK_NEW_PROFILE_WEBHOO= NEXT_PUBLIC_OPENSEA_API_KEYS= -NEXT_PUBLIC_COVALENT_API_KEYS=ckey_*,ckey_* NEXT_PUBLIC_CMC_PRO_API_KEYS= -NEXT_PUBLIC_REDIS_URL= + +SLACK_NEW_PROFILE_WEBHOOK= +COVALENT_API_KEYS=ckey_*,ckey_* +SUPABASE_SERVICE_KEY= +REDIS_URL= diff --git a/packages/bento-web/package.json b/packages/bento-web/package.json index b2e3cd32..b5283b47 100644 --- a/packages/bento-web/package.json +++ b/packages/bento-web/package.json @@ -1,6 +1,6 @@ { "name": "@bento/web", - "version": "1.3.30", + "version": "1.3.31", "private": true, "scripts": { "dev": "env-cmd -f .env.debug.local next dev", diff --git a/packages/bento-web/pages/api/auth/index.ts b/packages/bento-web/pages/api/auth/index.ts index b7673868..3d4e58e1 100644 --- a/packages/bento-web/pages/api/auth/index.ts +++ b/packages/bento-web/pages/api/auth/index.ts @@ -1,9 +1,8 @@ import { NextApiRequest, NextApiResponse } from 'next'; +import { ServerSupabase as Supabase } from '@/utils/ServerSupabase'; import { withCORS } from '@/utils/middlewares/withCORS'; -import { Supabase } from '@/utils'; - const handler = async (req: NextApiRequest, res: NextApiResponse) => { if (req.method === 'POST') { Supabase.auth.api.setAuthCookie(req, res); diff --git a/packages/bento-web/pages/api/auth/verify/[walletType].ts b/packages/bento-web/pages/api/auth/verify/[walletType].ts index 88069cec..fbb15354 100644 --- a/packages/bento-web/pages/api/auth/verify/[walletType].ts +++ b/packages/bento-web/pages/api/auth/verify/[walletType].ts @@ -9,10 +9,9 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import nacl from 'tweetnacl'; import { createRedisClient } from '@/utils/Redis'; +import { ServerSupabase as Supabase } from '@/utils/ServerSupabase'; import { withCORS } from '@/utils/middlewares/withCORS'; -import { Supabase } from '@/utils'; - type APIRequest = NextApiRequest & ( | { diff --git a/packages/bento-web/pages/api/defis/klaytn/[walletAddress].ts b/packages/bento-web/pages/api/defis/klaytn/[walletAddress].ts index fa6315d5..b70168fb 100644 --- a/packages/bento-web/pages/api/defis/klaytn/[walletAddress].ts +++ b/packages/bento-web/pages/api/defis/klaytn/[walletAddress].ts @@ -18,6 +18,7 @@ import { KlaySwap } from '@/defi/klaytn/klayswap'; import { KokonutSwap } from '@/defi/klaytn/kokonutswap'; import { Swapscanner } from '@/defi/klaytn/swapscanner'; import { SCNR_ADDRESS } from '@/defi/klaytn/swapscanner/constants'; +import { withoutEmptyDeFiStaking } from '@/defi/klaytn/utils/withoutEmptyDeFiStaking'; import { DeFiStaking } from '@/defi/types/staking'; interface APIRequest extends NextApiRequest { @@ -229,5 +230,5 @@ const getDeFiStakingsByWalletAddress = async ( ]) ).flat(); - return stakings; + return stakings.filter(withoutEmptyDeFiStaking); }; diff --git a/packages/bento-web/pages/api/defis/osmosis/[walletAddress].ts b/packages/bento-web/pages/api/defis/osmosis/[walletAddress].ts index 287a44c1..546b86f8 100644 --- a/packages/bento-web/pages/api/defis/osmosis/[walletAddress].ts +++ b/packages/bento-web/pages/api/defis/osmosis/[walletAddress].ts @@ -1,6 +1,7 @@ import { Bech32Address } from '@bento/core'; import { NextApiRequest, NextApiResponse } from 'next'; +import { withoutEmptyDeFiStaking } from '@/defi/klaytn/utils/withoutEmptyDeFiStaking'; import { IONDAO } from '@/defi/osmosis/ion-dao'; import { DeFiStaking } from '@/defi/types/staking'; @@ -26,6 +27,7 @@ const handler = async (req: APIRequest, res: NextApiResponse) => { let stakings: DeFiStaking[]; stakings = await getDeFiStakingsByWalletAddress(walletAddress); + stakings = stakings.filter(withoutEmptyDeFiStaking); res.status(200).json(stakings); }; diff --git a/packages/bento-web/pages/api/profile/blocks.ts b/packages/bento-web/pages/api/profile/blocks.ts index f2c82285..34c4109b 100644 --- a/packages/bento-web/pages/api/profile/blocks.ts +++ b/packages/bento-web/pages/api/profile/blocks.ts @@ -1,9 +1,9 @@ import type { NextApiRequest, NextApiResponse } from 'next'; +import { ServerSupabase as Supabase } from '@/utils/ServerSupabase'; import { withCORS } from '@/utils/middlewares/withCORS'; import { Block } from '@/profile/blocks'; -import { Supabase } from '@/utils'; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const { user } = await Supabase.auth.api.getUserByCookie(req); diff --git a/packages/bento-web/pages/api/profile/delete-wallet.ts b/packages/bento-web/pages/api/profile/delete-wallet.ts index 1235b723..bab93d54 100644 --- a/packages/bento-web/pages/api/profile/delete-wallet.ts +++ b/packages/bento-web/pages/api/profile/delete-wallet.ts @@ -1,10 +1,10 @@ import { PostgrestError, PostgrestResponse } from '@supabase/supabase-js'; import type { NextApiRequest, NextApiResponse } from 'next'; +import { ServerSupabase as Supabase } from '@/utils/ServerSupabase'; import { withCORS } from '@/utils/middlewares/withCORS'; import { UserProfile } from '@/profile/types/UserProfile'; -import { Supabase } from '@/utils'; type APIRequest = NextApiRequest & { body: UserProfile; diff --git a/packages/bento-web/pages/api/profile/index.ts b/packages/bento-web/pages/api/profile/index.ts index cbfa8dea..255b409d 100644 --- a/packages/bento-web/pages/api/profile/index.ts +++ b/packages/bento-web/pages/api/profile/index.ts @@ -6,7 +6,7 @@ import { withCORS } from '@/utils/middlewares/withCORS'; import { UserProfile } from '@/profile/types/UserProfile'; import { axios } from '@/utils'; -import { Config, Supabase } from '@/utils'; +import { Supabase } from '@/utils'; const MATCH_RULE = /^(?!.*\.\.)(?!.*\.$)[^\W][\w.]{0,37}$/; @@ -25,13 +25,13 @@ const capitalize = (value: string) => value.charAt(0).toUpperCase() + value.slice(1); const notifySlack = async (user: User, profile: UserProfile) => { - if (!Config.SLACK_NEW_PROFILE_WEBHOOK) { + if (!process.env.SLACK_NEW_PROFILE_WEBHOOK) { // disabled return; } const provider = user.app_metadata.provider; await axios - .post(Config.SLACK_NEW_PROFILE_WEBHOOK, { + .post(process.env.SLACK_NEW_PROFILE_WEBHOOK, { provider: capitalize(provider || 'none'), social_url: !provider ? 'No social link available' diff --git a/packages/bento-web/src/defi/klaytn/utils/withoutEmptyDeFiStaking.ts b/packages/bento-web/src/defi/klaytn/utils/withoutEmptyDeFiStaking.ts new file mode 100644 index 00000000..67b327a8 --- /dev/null +++ b/packages/bento-web/src/defi/klaytn/utils/withoutEmptyDeFiStaking.ts @@ -0,0 +1,33 @@ +import { AmountWithOptionalValue, DeFiStaking } from '@/defi/types/staking'; + +export const withoutEmptyDeFiStaking = (staking: DeFiStaking) => { + if (isAmountExist(staking.staked) || isAmountExist(staking.rewards)) { + return true; + } + if (!!staking.unstake && staking.unstake !== 'unavailable') { + if ( + isAmountExist(staking.unstake.claimable) || + isAmountExist(staking.unstake.pending) + ) { + return true; + } + } + return false; +}; + +const isAmountExist = ( + value: AmountWithOptionalValue | 'unavailable' | null, +) => { + if (!!value && value !== 'unavailable') { + if ((value.lpAmount || 0) > 0) { + return true; + } + if ( + !!value.tokenAmounts && + Object.values(value.tokenAmounts).some((v) => (v || 0) > 0) + ) { + return true; + } + } + return false; +}; diff --git a/packages/bento-web/src/utils/Redis.ts b/packages/bento-web/src/utils/Redis.ts index 3eaf0488..b5ae2288 100644 --- a/packages/bento-web/src/utils/Redis.ts +++ b/packages/bento-web/src/utils/Redis.ts @@ -1,9 +1,8 @@ -import { Config } from '@bento/common'; import { createClient } from 'redis'; export const createRedisClient = () => { const redisClient = createClient({ - url: Config.REDIS_URL, + url: process.env.REDIS_URL, }); redisClient.on('error', (err) => console.error('Redis Client Error', err)); return redisClient; diff --git a/packages/bento-web/src/utils/ServerSupabase.ts b/packages/bento-web/src/utils/ServerSupabase.ts new file mode 100644 index 00000000..fedf0857 --- /dev/null +++ b/packages/bento-web/src/utils/ServerSupabase.ts @@ -0,0 +1,8 @@ +import { createClient } from '@supabase/supabase-js'; + +import { Config } from './Config'; + +export const ServerSupabase = createClient( + Config.SUPABASE_URL, + process.env.SUPABASE_SERVICE_KEY || '', +);