Skip to content

Commit

Permalink
ENG-5262 feat(portal): update protocol points from legacy api to grap…
Browse files Browse the repository at this point in the history
…hql (#1007)

## Affected Packages

Apps

- [ ] data populator
- [x] portal
- [ ] template

Packages

- [ ] 1ui
- [ ] api
- [ ] graphql
- [ ] protocol
- [ ] sdk

Tools

- [ ] tools

## Overview

Overview of the changes in the PR.

## Screen Captures

If applicable, add screenshots or screen captures of your changes.

## Declaration

- [x] I hereby declare that I have abided by the rules and regulations
as outlined in the
[CONTRIBUTING.md](https://github.com/0xIntuition/intuition-ts/blob/main/CONTRIBUTING.md)
  • Loading branch information
Vitalsine85 authored Dec 27, 2024
1 parent b20a059 commit 604babf
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 48 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ jobs:
--build-arg PHOSPHOR_COLLECTION_ID=${{ secrets.PHOSPHOR_COLLECTION_ID }} \
--build-arg GTM_TRACKING_ID=${{ secrets.GTM_TRACKING_ID }} \
--build-arg RELIC_GRAPHQL_ENDPOINT=${{ secrets.RELIC_GRAPHQL_ENDPOINT }} \
--build-arg I7N_GRAPHQL_ENDPOINT=${{ secrets.I7N_GRAPHQL_ENDPOINT }} \
--build-arg FF_FULL_LOCKDOWN_ENABLED=false \
--build-arg FF_GENERIC_BANNER_ENABLED=true \
--build-arg FF_INCIDENT_BANNER_ENABLED=false
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy_production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ jobs:
--build-arg PHOSPHOR_COLLECTION_ID=${{ secrets.PHOSPHOR_COLLECTION_ID }} \
--build-arg GTM_TRACKING_ID=${{ secrets.GTM_TRACKING_ID }} \
--build-arg RELIC_GRAPHQL_ENDPOINT=${{ secrets.RELIC_GRAPHQL_ENDPOINT }} \
--build-arg I7N_GRAPHQL_ENDPOINT=${{ secrets.I7N_GRAPHQL_ENDPOINT }} \
--build-arg FF_FULL_LOCKDOWN_ENABLED=false \
--build-arg FF_GENERIC_BANNER_ENABLED=false \
--build-arg FF_INCIDENT_BANNER_ENABLED=false
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy_staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ jobs:
--build-arg PHOSPHOR_COLLECTION_ID=${{ secrets.PHOSPHOR_COLLECTION_ID }} \
--build-arg GTM_TRACKING_ID=${{ secrets.GTM_TRACKING_ID }} \
--build-arg RELIC_GRAPHQL_ENDPOINT=${{ secrets.RELIC_GRAPHQL_ENDPOINT }} \
--build-arg I7N_GRAPHQL_ENDPOINT=${{ secrets.I7N_GRAPHQL_ENDPOINT }} \
--build-arg FF_FULL_LOCKDOWN_ENABLED=false \
--build-arg FF_INCIDENT_BANNER_ENABLED=false \
--build-arg FF_GENERIC_BANNER_ENABLED=false
Expand Down
3 changes: 2 additions & 1 deletion apps/portal/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ARG FF_INCIDENT_BANNER_ENABLED=${FF_INCIDENT_BANNER_ENABLED}
ARG FF_GENERIC_BANNER_ENABLED=${FF_GENERIC_BANNER_ENABLED}
ARG VITE_DEPLOY_ENV=${VITE_DEPLOY_ENV}
ARG RELIC_GRAPHQL_ENDPOINT=${RELIC_GRAPHQL_ENDPOINT}
ARG I7N_GRAPHQL_ENDPOINT=${I7N_GRAPHQL_ENDPOINT}

ENV ALCHEMY_MAINNET_API_KEY=${ALCHEMY_MAINNET_API_KEY}
ENV ALCHEMY_API_KEY=${ALCHEMY_API_KEY}
Expand Down Expand Up @@ -59,7 +60,7 @@ ENV FF_INCIDENT_BANNER_ENABLED=${FF_INCIDENT_BANNER_ENABLED}
ENV FF_GENERIC_BANNER_ENABLED=${FF_GENERIC_BANNER_ENABLED}
ENV VITE_DEPLOY_ENV=${VITE_DEPLOY_ENV}
ENV RELIC_GRAPHQL_ENDPOINT=${RELIC_GRAPHQL_ENDPOINT}

ENV I7N_GRAPHQL_ENDPOINT=${I7N_GRAPHQL_ENDPOINT}
WORKDIR /app

COPY package.json \
Expand Down
110 changes: 110 additions & 0 deletions apps/portal/app/lib/services/protocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
interface GraphQLResponse<T> {
data?: T
errors?: Array<{ message: string }>
}

const GetFeeTransfersDocument = {
query: `
query GetFeeTransfers($address: String!, $cutoff_timestamp: bigint) {
before_cutoff: fee_transfers_aggregate(
where: { block_timestamp: { _lte: $cutoff_timestamp }, sender_id: { _eq: $address } }
) {
aggregate {
sum {
amount
}
}
}
after_cutoff: fee_transfers_aggregate(
where: { block_timestamp: { _gt: $cutoff_timestamp }, sender_id: { _eq: $address } }
) {
aggregate {
sum {
amount
}
}
}
}
`,
} as const

interface GetFeeTransfersQuery {
before_cutoff: {
aggregate: {
sum: {
amount: string
}
}
}
after_cutoff: {
aggregate: {
sum: {
amount: string
}
}
}
}

interface GetFeeTransfersQueryVariables {
address: string
cutoff_timestamp: number
}

async function fetchGraphQL<T, V>(
document: { query: string },
variables: V,
): Promise<GraphQLResponse<T>> {
const endpoint = process.env.I7N_GRAPHQL_ENDPOINT
if (!endpoint) {
throw new Error('I7N_GRAPHQL_ENDPOINT not configured')
}

const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: document.query,
variables,
}),
})

if (!response.ok) {
throw new Error(`GraphQL request failed: ${response.statusText}`)
}

return response.json()
}

export async function fetchProtocolFees(address: string) {
const cutoffTimestamp = 1733356800

const feeData = await fetchGraphQL<
GetFeeTransfersQuery,
GetFeeTransfersQueryVariables
>(GetFeeTransfersDocument, {
address,
cutoff_timestamp: cutoffTimestamp,
})

const beforeCutoffAmount =
feeData?.data?.before_cutoff?.aggregate?.sum?.amount ?? '0'
const afterCutoffAmount =
feeData?.data?.after_cutoff?.aggregate?.sum?.amount ?? '0'

const beforeCutoffPoints =
(BigInt(beforeCutoffAmount) * BigInt(10000000)) / BigInt(1e18)
const afterCutoffPoints =
(BigInt(afterCutoffAmount) * BigInt(1000000)) / BigInt(1e18)
const totalPoints = beforeCutoffPoints + afterCutoffPoints

return {
beforeCutoffAmount,
afterCutoffAmount,
beforeCutoffPoints: beforeCutoffPoints.toString(),
afterCutoffPoints: afterCutoffPoints.toString(),
totalPoints: totalPoints.toString(),
}
}
18 changes: 13 additions & 5 deletions apps/portal/app/routes/app+/profile+/$wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ import { getSpecialPredicate } from '@lib/utils/app'
import logger from '@lib/utils/logger'
import {
calculatePercentageOfTvl,
calculatePointsFromFees,
formatBalance,
getAtomImage,
getAtomLabel,
Expand All @@ -73,6 +72,7 @@ import {
userIdentityRouteOptions,
} from 'app/consts'
import TwoPanelLayout from 'app/layouts/two-panel-layout'
import { fetchProtocolFees } from 'app/lib/services/protocol'
import { fetchRelicCounts } from 'app/lib/services/relic'
import { VaultDetailsType } from 'app/types/vault'
import { useAtom } from 'jotai'
Expand Down Expand Up @@ -137,7 +137,10 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
return logger('No user totals found')
}

const relicCounts = await fetchRelicCounts(wallet.toLowerCase())
const [relicCounts, protocolFees] = await Promise.all([
fetchRelicCounts(wallet.toLowerCase()),
fetchProtocolFees(wallet.toLowerCase()),
])

let vaultDetails: VaultDetailsType | null = null

Expand Down Expand Up @@ -206,6 +209,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
isPending,
relicHoldCount: relicCounts.holdCount,
relicMintCount: relicCounts.mintCount,
protocolFees,
})
}

Expand All @@ -222,6 +226,7 @@ export default function Profile() {
isPending,
relicMintCount,
relicHoldCount,
protocolFees,
} = useLiveLoader<{
wallet: string
userWallet: string
Expand All @@ -234,6 +239,11 @@ export default function Profile() {
isPending: boolean
relicMintCount: number
relicHoldCount: number
protocolFees: {
beforeCutoffPoints: string
afterCutoffPoints: string
totalPoints: string
}
}>(['attest', 'create'])
const navigate = useNavigate()

Expand All @@ -260,13 +270,11 @@ export default function Profile() {
const nftHoldPoints = relicHoldCount ? relicHoldCount * 250000 : 0
const totalNftPoints = nftMintPoints + nftHoldPoints

const feePoints = calculatePointsFromFees(userTotals.total_protocol_fee_paid)

const totalPoints =
userTotals.referral_points +
userTotals.quest_points +
totalNftPoints +
feePoints
parseInt(protocolFees.totalPoints)

const leftPanel = (
<div className="flex-col justify-start items-start gap-5 inline-flex max-lg:w-full">
Expand Down
18 changes: 13 additions & 5 deletions apps/portal/app/routes/app+/profile+/_index+/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import { getSpecialPredicate } from '@lib/utils/app'
import logger from '@lib/utils/logger'
import {
calculatePercentageOfTvl,
calculatePointsFromFees,
formatBalance,
getAtomImage,
getAtomLabel,
Expand All @@ -79,6 +78,7 @@ import {
userIdentityRouteOptions,
} from 'app/consts'
import TwoPanelLayout from 'app/layouts/two-panel-layout'
import { fetchProtocolFees } from 'app/lib/services/protocol'
import { fetchRelicCounts } from 'app/lib/services/relic'
import { VaultDetailsType } from 'app/types/vault'
import { useAtom } from 'jotai'
Expand All @@ -89,7 +89,10 @@ export async function loader({ request }: LoaderFunctionArgs) {
invariant(user.wallet?.address, 'User wallet not found')
const userWallet = user.wallet?.address

const relicCounts = await fetchRelicCounts(userWallet.toLowerCase())
const [relicCounts, protocolFees] = await Promise.all([
fetchRelicCounts(userWallet.toLowerCase()),
fetchProtocolFees(userWallet.toLowerCase()),
])

const userObject = await fetchWrapper(request, {
method: UsersService.getUserByWalletPublic,
Expand Down Expand Up @@ -194,6 +197,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
isPending,
relicHoldCount: relicCounts.holdCount,
relicMintCount: relicCounts.mintCount,
protocolFees,
})
}

Expand All @@ -209,6 +213,11 @@ export interface ProfileLoaderData {
isPending: boolean
relicMintCount: number
relicHoldCount: number
protocolFees: {
beforeCutoffPoints: string
afterCutoffPoints: string
totalPoints: string
}
}

export default function Profile() {
Expand All @@ -223,6 +232,7 @@ export default function Profile() {
isPending,
relicMintCount,
relicHoldCount,
protocolFees,
} = useLiveLoader<ProfileLoaderData>(['attest', 'create'])

const { user_assets, assets_sum } = vaultDetails ? vaultDetails : userIdentity
Expand Down Expand Up @@ -284,13 +294,11 @@ export default function Profile() {
const nftHoldPoints = relicHoldCount * 250000
const totalNftPoints = nftMintPoints + nftHoldPoints

const feePoints = calculatePointsFromFees(userTotals.total_protocol_fee_paid)

const totalPoints =
userTotals.referral_points +
userTotals.quest_points +
totalNftPoints +
feePoints
parseInt(protocolFees.totalPoints)

const leftPanel = (
<div className="flex-col justify-start items-start gap-5 inline-flex max-lg:w-full">
Expand Down
27 changes: 17 additions & 10 deletions apps/portal/app/routes/app+/quest+/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { PointsEarnedCard } from '@components/points-card/points-card'
import { QuestSetProgressCard } from '@components/quest/quest-set-progress-card'
import { ReferralCard } from '@components/referral-card/referral-card'
import RelicPointCard from '@components/relic-point-card/relic-point-card'
import { calculatePointsFromFees, invariant } from '@lib/utils/misc'
import { invariant } from '@lib/utils/misc'
import { LoaderFunctionArgs } from '@remix-run/node'
import { Await, useLoaderData } from '@remix-run/react'
import { fetchWrapper } from '@server/api'
Expand All @@ -31,14 +31,18 @@ import {
HEADER_BANNER_HELP_CENTER,
STANDARD_QUEST_SET,
} from 'app/consts'
import { fetchProtocolFees } from 'app/lib/services/protocol'
import { fetchRelicCounts } from 'app/lib/services/relic'
import { isAddress } from 'viem'

export async function loader({ request }: LoaderFunctionArgs) {
const userWallet = await requireUserWallet(request)
invariant(userWallet, 'Unauthorized')

const relicCounts = await fetchRelicCounts(userWallet.toLowerCase())
const [relicCounts, protocolFees] = await Promise.all([
fetchRelicCounts(userWallet.toLowerCase()),
fetchProtocolFees(userWallet.toLowerCase()),
])

const userProfile = await fetchWrapper(request, {
method: UsersService.getUserByWalletPublic,
Expand Down Expand Up @@ -76,12 +80,19 @@ export async function loader({ request }: LoaderFunctionArgs) {
inviteCodes: inviteCodes.invite_codes,
relicHoldCount: relicCounts.holdCount,
mintCount: relicCounts.mintCount,
protocolFees,
}
}

export default function Quests() {
const { userTotals, inviteCodes, mintCount, relicHoldCount, details } =
useLoaderData<typeof loader>()
const {
userTotals,
inviteCodes,
mintCount,
relicHoldCount,
protocolFees,
details,
} = useLoaderData<typeof loader>()

const nftMintPoints = mintCount * 2000000
const nftHoldPoints = relicHoldCount * 250000
Expand Down Expand Up @@ -131,9 +142,7 @@ export default function Quests() {
resolvedUserTotals.referral_points +
resolvedUserTotals.quest_points +
totalNftPoints +
calculatePointsFromFees(
resolvedUserTotals.total_protocol_fee_paid,
)
parseInt(protocolFees.totalPoints)
}
activities={[
{
Expand All @@ -142,9 +151,7 @@ export default function Quests() {
},
{
name: 'Protocol',
points: calculatePointsFromFees(
resolvedUserTotals.total_protocol_fee_paid,
),
points: parseInt(protocolFees.totalPoints),
},
{
name: 'NFT',
Expand Down
Loading

0 comments on commit 604babf

Please sign in to comment.