Skip to content

Commit

Permalink
Centrifuge App: Fetch DAO data dynamically (#1755)
Browse files Browse the repository at this point in the history
* Fetch dao config from public github repo

* Remove author

* Remove showPortfolio debug flag
  • Loading branch information
sophialittlejohn authored Dec 8, 2023
1 parent c25825d commit ee974d5
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 115 deletions.
5 changes: 0 additions & 5 deletions centrifuge-app/src/components/DebugFlags/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export type Key =
| 'editAdminConfig'
| 'showPodAccountCreation'
| 'convertAddress'
| 'showPortfolio'
| 'showTestNets'
| 'showSwaps'
| 'showPrime'
Expand Down Expand Up @@ -114,10 +113,6 @@ export const flagsConfig: Record<Key, DebugFlagConfig> = {
default: null,
alwaysShow: true,
},
showPortfolio: {
type: 'checkbox',
default: false,
},
showSwaps: {
type: 'checkbox',
default: false,
Expand Down
6 changes: 3 additions & 3 deletions centrifuge-app/src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function Menu() {
const pools = usePoolsThatAnyConnectedAddressHasPermissionsFor() || []
const isLarge = useIsAboveBreakpoint('L')
const address = useAddress('substrate')
const { showSwaps, showPortfolio, showPrime } = useDebugFlags()
const { showSwaps, showPrime } = useDebugFlags()

return (
<Shelf
Expand All @@ -48,14 +48,14 @@ export function Menu() {
</PageLink>
)}

{showPortfolio && address && (
{address && (
<PageLink to="/portfolio" stacked={!isLarge}>
<IconPieChart />
Portfolio
</PageLink>
)}

{showPortfolio && address && (
{address && (
<PageLink to="/history" stacked={!isLarge}>
<IconClock />
History
Expand Down
29 changes: 2 additions & 27 deletions centrifuge-app/src/components/PortfolioCta/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Dec } from '../../utils/Decimal'
import { formatBalance, formatBalanceAbbreviated } from '../../utils/formatting'
import { useAddress } from '../../utils/useAddress'
import { useListedPools } from '../../utils/useListedPools'
import { useDebugFlags } from '../DebugFlags'
import { useComputeLiquidityRewards } from '../LiquidityRewards/hooks'
import { Cubes } from './Cubes'

Expand All @@ -18,7 +17,6 @@ export function PortfolioCta() {
const balances = useBalances(address)
const consts = useCentrifugeConsts()
const [, listedTokens] = useListedPools()
const { showPortfolio } = useDebugFlags()

const stakes = balances?.tranches.map(({ poolId, trancheId }) => ({ poolId, trancheId })) ?? []
const rewards = useComputeLiquidityRewards(address, stakes)
Expand All @@ -44,7 +42,7 @@ export function PortfolioCta() {
},
]

return showPortfolio ? (
return (
<Box
as="article"
position="relative"
Expand Down Expand Up @@ -90,28 +88,5 @@ export function PortfolioCta() {
)}
</Stack>
</Box>
) : !address ? (
<Box
as="article"
position="relative"
p={3}
pb={5}
overflow="hidden"
borderRadius="card"
borderStyle="solid"
borderWidth={1}
borderColor={'borderSecondary'}
style={{
boxShadow: `0px 3px 2px -2px ${colors.borderPrimary}`,
}}
>
{!address && <Cubes />}
<Stack gap={2} alignItems="start">
<Text as="h2" variant="body1" style={{ maxWidth: '35ch' }}>
Pools on Centrifuge let investors earn yield from real-world assets.
</Text>
<Button onClick={() => showNetworks()}>Get started</Button>
</Stack>
</Box>
) : null
)
}
51 changes: 11 additions & 40 deletions centrifuge-app/src/components/Resolutions.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,18 @@
import { Box, Shelf, Stack, Text } from '@centrifuge/fabric'
import { Shelf, Stack, Text } from '@centrifuge/fabric'
import styled from 'styled-components'
import aaveBlog from '../assets/images/aave-blog.png'
import { DAO } from '../utils/useDAOConfig'

const blogs = [
{
title: '[ARFC] Aave Treasury RWA Allocation',
date: ' Sep 7, 2023',
author: 'Asad Khan',
excerpt:
'This proposal brings on Centrifuge as a service provider to the Aave DAO to setup a legal structure to support RWA investments, develop RWA specific management and governance processes, and allocate $1M of the Aave Treasury’s stablecoin holdings to a liquid US T-Bill fund on Centrifuge, as a proof of concept investment.',
link: 'https://governance.aave.com/t/arfc-aave-treasury-rwa-allocation/14790',
},
{
title: '[ARFC] Aave Treasury Proposal for RWA Allocation Snapshot Vote',
date: 'Sep 12, 2023',
author: 'Asad Khan',
excerpt:
'This is a first step towards a long term effort for Aave to develop and launch an RWA Facilitator that will back GHO with Real World Assets. With this proposal Aave can earn yield on idle stablecoins, establish long-term RWA infrastructure for the protocol, and allow the Aave DAO to begin building internal familiarity and expertise in the RWA industry.',
link: 'https://snapshot.org/#/aave.eth/proposal/0x71db494e4b49e7533c5ccaa566686b2d045b0761cb3296a2d77af4b500566eb0',
},
{
title: 'Draft Documents for Aave RWA Legal Structure',
date: 'Oct 31, 2023',
author: 'Asad Khan',
excerpt:
'We have developed an initial draft of the legal documents that will define the Aave’s DAO RWA legal structure. We have shared the below summary and documents with core contributors and delegates for feedback with no issues identified.',
link: 'https://governance.aave.com/t/draft-documents-for-aave-rwa-legal-structure/15283',
},
]

export const Resolutions = () => {
export const Resolutions = ({ dao }: { dao: DAO }) => {
return (
<Stack as="article" gap={2}>
<Text as="h2" variant="heading2">
Resolutions
</Text>
<Shelf alignItems="flex-start" gap={3}>
{blogs.map((blog) => (
{dao.resolutions.map((blog) => (
<HoverableCard
width="282px"
height="426px"
height="400px"
as="a"
href={blog.link}
key={blog.title}
Expand All @@ -52,20 +25,18 @@ export const Resolutions = () => {
rel="noopener noreferrer"
borderRadius="4px"
>
<img src={aaveBlog} alt={blog.title} width="100%" height="auto" />
<img src={blog.image} alt={blog.title} width="100%" height="auto" />
<Text variant="body2">{blog.title}</Text>
<Text variant="body4" color="textSecondary">
{blog.date}
{new Date(blog.timestamp * 1000).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</Text>
<Text variant="body3" color="textSecondary">
{blog.excerpt}
</Text>
<Shelf gap="10px">
<Box height="19px" width="19px" borderRadius="100%" backgroundColor="yellowScale.100" />
<Text variant="body2" color="textSecondary">
{blog.author}
</Text>
</Shelf>
</HoverableCard>
))}
</Shelf>
Expand Down
20 changes: 0 additions & 20 deletions centrifuge-app/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { TransactionOptions } from '@centrifuge/centrifuge-js'
import { Network } from '@centrifuge/centrifuge-react'
import { altairDark, centrifugeLight } from '@centrifuge/fabric'
import * as React from 'react'
import { DefaultTheme } from 'styled-components'
import aaveLogo from './assets/images/aave-token-logo.svg'
import { LogoAltair, LogoAltairText } from './components/LogoAltair'
import { LogoCentrifuge, LogoCentrifugeText } from './components/LogoCentrifuge'

Expand Down Expand Up @@ -144,24 +142,6 @@ export const ethConfig = {

export const config = import.meta.env.REACT_APP_NETWORK === 'altair' ? ALTAIR : CENTRIFUGE

export type DAO = {
slug: string
name: string
network: Network
address: string
icon: string
}

export const DAOs: DAO[] = [
{
slug: 'aave',
name: 'Aave',
network: 'centrifuge',
address: 'kALNreUp6oBmtfG87fe7MakWR8BnmQ4SmKjjfG27iVd3nuTue',
icon: aaveLogo,
},
]

export const parachainNames: Record<number, string> = {
1000: 'Asset Hub',
}
26 changes: 14 additions & 12 deletions centrifuge-app/src/pages/Prime/Detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Holdings } from '../../components/Portfolio/Holdings'
import { Transactions } from '../../components/Portfolio/Transactions'
import { Resolutions } from '../../components/Resolutions'
import { RouterTextLink } from '../../components/TextLink'
import { DAOs } from '../../config'
import { useDAOConfig } from '../../utils/useDAOConfig'

export default function PrimeDetailPage() {
return (
Expand All @@ -20,14 +20,16 @@ export default function PrimeDetailPage() {

function PrimeDetail() {
const { dao: daoSlug } = useParams<{ dao: string }>()
const dao = DAOs.find((d) => d.slug === daoSlug)
const { data: DAOs, isLoading } = useDAOConfig()
const dao = DAOs?.find((d) => d.slug === daoSlug)
const utils = useCentrifugeUtils()
if (!dao) throw new Error('DAO not found')
const centAddress = utils.formatAddress(
typeof dao.network === 'number' ? utils.evmToSubstrateAddress(dao.address, dao.network) : dao.address
)
const centAddress =
dao &&
utils.formatAddress(
typeof dao.network === 'number' ? utils.evmToSubstrateAddress(dao.address, dao.network) : dao.address
)

return (
return !isLoading && dao && centAddress ? (
<>
<LayoutSection backgroundColor="backgroundSecondary" alignItems="flex-start" pt={5}>
<Text variant="body3">
Expand All @@ -36,18 +38,18 @@ function PrimeDetail() {
Prime
</RouterTextLink>
</Text>{' '}
/ {dao.name} DAO Investments
/ {dao.name} Investments
</Text>
<Shelf gap={2}>
<Box as="img" src={dao.icon} alt={dao.name} width="iconRegular" height="iconRegular" borderRadius="50%" />
<Text variant="heading1">{dao.name} DAO Investments</Text>
<Box as="img" src={dao.logo} alt={dao.name} width="iconRegular" height="iconRegular" borderRadius="50%" />
<Text variant="heading1">{dao.name} Investments</Text>
</Shelf>
</LayoutSection>
<BasePadding gap={3}>
<Holdings address={centAddress} />
<Transactions onlyMostRecent address={centAddress} />
<Resolutions />
<Resolutions dao={dao} />
</BasePadding>
</>
)
) : null
}
18 changes: 10 additions & 8 deletions centrifuge-app/src/pages/Prime/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { firstValueFrom } from 'rxjs'
import { Column, DataTable, FilterableTableHeader, SortableTableHeader } from '../../components/DataTable'
import { LayoutBase } from '../../components/LayoutBase'
import { LayoutSection } from '../../components/LayoutBase/LayoutSection'
import { DAO, DAOs } from '../../config'
import { formatDate } from '../../utils/date'
import { formatBalance, formatPercentage } from '../../utils/formatting'
import { DAO, useDAOConfig } from '../../utils/useDAOConfig'
import { useFilters } from '../../utils/useFilters'
import { useSubquery } from '../../utils/useSubquery'

Expand Down Expand Up @@ -55,13 +55,15 @@ function DaoPortfoliosTable() {
const utils = useCentrifugeUtils()
const cent = useCentrifuge()
const getNetworkName = useGetNetworkName()
const { data: daoData } = useDAOConfig()

const daos = DAOs.map((dao) => ({
...dao,
address: utils.formatAddress(
typeof dao.network === 'number' ? utils.evmToSubstrateAddress(dao.address, dao.network) : dao.address
),
}))
const daos =
daoData?.map((dao) => ({
...dao,
address: utils.formatAddress(
typeof dao.network === 'number' ? utils.evmToSubstrateAddress(dao.address, dao.network) : dao.address
),
})) || []

// TODO: Update to use new portfolio Runtime API
const { data, isLoading: isPortfoliosLoading } = useQuery(['daoPortfolios', daos.map((dao) => dao.address)], () =>
Expand Down Expand Up @@ -130,7 +132,7 @@ function DaoPortfoliosTable() {
header: 'DAO',
cell: (row: Row) => (
<Shelf gap={1}>
<Box as="img" src={row.icon} alt={row.name} width="iconSmall" height="iconSmall" borderRadius="50%" />
<Box as="img" src={row.logo} alt={row.name} width="iconSmall" height="iconSmall" borderRadius="50%" />
<Text>{row.name}</Text>
</Shelf>
),
Expand Down
51 changes: 51 additions & 0 deletions centrifuge-app/src/utils/useDAOConfig.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Network } from '@centrifuge/centrifuge-react'
import { useQuery } from 'react-query'
import { isTestEnv } from '../config'

export type DAO = {
name: string
slug: string
network: Network
logo: string
address: string
resolutions: Resolution[]
}

export type Resolution = {
title: string
image: string
timestamp: number
excerpt: string
link: string
}

export const useDAOConfig = () => {
const query = useQuery(
'daoData',
async () => {
const res = await fetch(
`https://api.github.com/repos/centrifuge/prime-data/contents/data${isTestEnv ? '-dev' : ''}.json`,
{
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
}
)

if (!res.ok) {
throw new Error('Network response was not ok')
}

const json = await res.json()
const content = atob(json.content)

const data = JSON.parse(content)
return Object.values(data) as DAO[]
},
{
staleTime: Infinity,
}
)
return query
}

0 comments on commit ee974d5

Please sign in to comment.