Skip to content

Commit

Permalink
Improve LP pool setup, fix pricing section, add base sepolia (#2376)
Browse files Browse the repository at this point in the history
* Batch LP pool setup calls

* Improve UI

* Make button full width

* Cleanup

* Add icon

* Add base sepolia, add warning if domain is not set up yet

* Naming

* Move onboarding settings to configuration page

* Remove goerli networks

* Improve pricing section of asset page
  • Loading branch information
hieronx authored Aug 15, 2024
1 parent 4d51bc1 commit 4d308e3
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Row = {
toAssetName?: string
amount: CurrencyBalance | undefined
hash: string
netFlow?: 'positive' | 'negative' | 'neutral'
}

const getTransactionTypeStatus = (type: string): 'default' | 'info' | 'ok' | 'warning' | 'critical' => {
Expand Down
4 changes: 4 additions & 0 deletions centrifuge-app/src/components/Tooltips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ export const tooltipText = {
label: 'Available balance',
body: 'Unlimited because this is a virtual accounting process.',
},
linearAccrual: {
label: 'Linear accrual',
body: 'If enabled, the price of the asset is updated continuously based on linear accrual from the latest known market price to the value at maturity.',
},
}

export type TooltipsProps = {
Expand Down
35 changes: 5 additions & 30 deletions centrifuge-app/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import assetHubLogo from '@centrifuge/fabric/assets/logos/assethub.svg'
import baseLogo from '@centrifuge/fabric/assets/logos/base.svg'
import celoLogo from '@centrifuge/fabric/assets/logos/celo.svg'
import ethereumLogo from '@centrifuge/fabric/assets/logos/ethereum.svg'
import goerliLogo from '@centrifuge/fabric/assets/logos/goerli.svg'
import sepoliaLogo from '@centrifuge/fabric/assets/logos/sepolia.png'
import * as React from 'react'
import { DefaultTheme } from 'styled-components'
Expand Down Expand Up @@ -175,18 +174,6 @@ export const evmChains: EvmChains = {
iconUrl: ethereumLogo,
isTestnet: false,
},
5: {
name: 'Ethereum Goerli',
nativeCurrency: {
name: 'Görli Ether',
symbol: 'görETH',
decimals: 18,
},
blockExplorerUrl: 'https://goerli.etherscan.io/',
urls: [`https://eth-sepolia.g.alchemy.com/v2/${alchemyKey}`],
iconUrl: goerliLogo,
isTestnet: true,
},
11155111: {
name: 'Ethereum Sepolia',
nativeCurrency: { name: 'Sepolia Ether', symbol: 'sepETH', decimals: 18 },
Expand All @@ -203,11 +190,11 @@ export const evmChains: EvmChains = {
iconUrl: baseLogo,
isTestnet: false,
},
84531: {
name: 'Base Goerli',
nativeCurrency: { name: 'Base Goerli Ether', symbol: 'gbETH', decimals: 18 },
blockExplorerUrl: 'https://goerli.basescan.org/',
urls: [`https://goerli.base.org`],
84532: {
name: 'Base Sepolia',
nativeCurrency: { name: 'Base Sepolia Ether', symbol: 'sbETH', decimals: 18 },
blockExplorerUrl: 'https://sepolia.basescan.org/',
urls: [`https://sepolia.base.org`],
iconUrl: baseLogo,
isTestnet: true,
},
Expand All @@ -223,18 +210,6 @@ export const evmChains: EvmChains = {
iconUrl: arbitrumLogo,
isTestnet: false,
},
421613: {
name: 'Arbitrum Goerli',
nativeCurrency: {
name: 'Ether',
symbol: 'ETH',
decimals: 18,
},
blockExplorerUrl: 'https://goerli.arbiscan.io/',
urls: [`https://arbitrum-goerli.infura.io/v3/${infuraKey}`],
iconUrl: arbitrumLogo,
isTestnet: true,
},
42220: {
name: 'Celo',
nativeCurrency: {
Expand Down
2 changes: 2 additions & 0 deletions centrifuge-app/src/pages/IssuerPool/Configuration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LayoutBase } from '../../../components/LayoutBase'
import { LoadBoundary } from '../../../components/LoadBoundary'
import { useCanBorrow, usePoolAdmin } from '../../../utils/usePermissions'
import { IssuerPoolHeader } from '../Header'
import { OnboardingSettings } from '../Investors/OnboardingSettings'
import { Details } from './Details'
import { EpochAndTranches } from './EpochAndTranches'
import { Issuer } from './Issuer'
Expand Down Expand Up @@ -39,6 +40,7 @@ function IssuerPoolConfiguration() {
<Issuer />
<EpochAndTranches />
<LoanTemplates />
{isPoolAdmin && <OnboardingSettings />}
{editPoolConfig && <PoolConfig poolId={poolId} />}
</>
)}
Expand Down
178 changes: 110 additions & 68 deletions centrifuge-app/src/pages/IssuerPool/Investors/LiquidityPools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,26 @@ import {
useCentrifugeApi,
useCentrifugeTransaction,
useGetExplorerUrl,
useGetNetworkIcon,
useGetNetworkName,
useNetworkName,
} from '@centrifuge/centrifuge-react'
import { Accordion, Button, IconExternalLink, Shelf, Stack, Text } from '@centrifuge/fabric'
import {
Accordion,
Box,
Button,
Grid,
IconExternalLink,
InlineFeedback,
Shelf,
Spinner,
Stack,
Text,
} from '@centrifuge/fabric'
import React from 'react'
import { useParams } from 'react-router'
import { combineLatest, switchMap } from 'rxjs'
import { PageSection } from '../../../components/PageSection'
import { AnchorTextLink } from '../../../components/TextLink'
import { find } from '../../../utils/helpers'
import { useEvmTransaction } from '../../../utils/tinlake/useEvmTransaction'
import { Domain, useActiveDomains } from '../../../utils/useLiquidityPools'
Expand All @@ -36,38 +47,52 @@ export function LiquidityPools() {

const { data: domains, refetch } = useActiveDomains(poolId)
const getName = useGetNetworkName()

const titles = {
inactive: 'Not active',
deploying: 'Action needed',
deployed: 'Active',
}
const getIcon = useGetNetworkIcon()

return (
<PageSection
title="Connected blockchains"
subtitle="View liquidity on all blockchains that this pool is connected to, and enable investments on new blockchains."
>
<Accordion
items={
domains?.map((domain) => ({
title: (
<>
{getName(domain.chainId)} <Text fontWeight={400}>- {titles[getDomainStatus(domain)]}</Text>
</>
),
body: <PoolDomain poolId={poolId} domain={domain} refetch={refetch} />,
})) ?? []
}
/>
<Grid height="fit-content" gridTemplateColumns={['1fr 1fr 1fr 1fr']} gap={[2, 2]}>
{domains ? (
domains.map((domain) => (
<Accordion
items={[
{
title: (
<Shelf gap="12px">
<Box
as="img"
src={getIcon(domain.chainId)}
alt=""
width="iconSmall"
height="iconSmall"
style={{ objectFit: 'contain' }}
bleedY="12px"
/>
<Text>
{getName(domain.chainId)}{' '}
{getDomainStatus(domain) === 'deploying' && <Text fontWeight={400}>- Action needed</Text>}
</Text>
</Shelf>
),
body: <PoolDomain poolId={poolId} domain={domain} refetch={refetch} />,
},
]}
/>
))
) : (
<Spinner />
)}
</Grid>
</PageSection>
)
}

function PoolDomain({ poolId, domain, refetch }: { poolId: string; domain: Domain; refetch: () => void }) {
const pool = usePool(poolId)
const poolAdmin = usePoolAdmin(poolId)
const getName = useGetNetworkName()
const explorer = useGetExplorerUrl(domain.chainId)
const api = useCentrifugeApi()

Expand All @@ -82,7 +107,17 @@ function PoolDomain({ poolId, domain, refetch }: { poolId: string; domain: Domai
)
).pipe(
switchMap((txs) => {
return cent.wrapSignAndSend(api, txs.length > 1 ? api.tx.utility.batchAll(txs) : txs[0], options)
return cent.wrapSignAndSend(
api,
txs.length > 1
? api.tx.utility.batchAll([
api.tx.liquidityPoolsGateway.startBatchMessage({ EVM: domain.chainId }),
...txs,
api.tx.liquidityPoolsGateway.endBatchMessage({ EVM: domain.chainId }),
])
: txs[0],
options
)
})
)
}
Expand All @@ -99,48 +134,57 @@ function PoolDomain({ poolId, domain, refetch }: { poolId: string; domain: Domai

return (
<Stack gap={1}>
{status === 'inactive' ? (
<EnableButton poolId={poolId} domain={domain} />
) : status === 'deploying' ? (
<ConnectionGuard networks={[domain.chainId]} body="Connect to the right network to continue" variant="plain">
{pool.tranches.map((t) => (
<React.Fragment key={t.id}>
{domain.canTrancheBeDeployed[t.id] && (
<DeployTrancheButton poolId={poolId} trancheId={t.id} domain={domain} onSuccess={refetch} />
)}
{domain.currencies.map((currency, i) => (
<React.Fragment key={i}>
{domain.trancheTokens[t.id] && !domain.liquidityPools[t.id][currency.address] && (
<DeployLPButton
poolId={poolId}
trancheId={t.id}
domain={domain}
currencyIndex={i}
onSuccess={refetch}
/>
)}
</React.Fragment>
))}
</React.Fragment>
))}
</ConnectionGuard>
) : (
pool.tranches.map((tranche) => (
<AnchorTextLink href={explorer.address(domain.trancheTokens[tranche.id])}>
<Shelf gap={1}>
<span>
See {tranche.currency.name} token on {getName(domain.chainId)}
</span>
<IconExternalLink size="iconSmall" />
</Shelf>
</AnchorTextLink>
))
)}
{domain.hasDeployedLp && (
<Button onClick={updateTokenPrices} loading={isLoading} small>
<Button onClick={updateTokenPrices} variant="primary" loading={isLoading} small>
Update token prices
</Button>
)}

{domain.currencies.length === 0 && (
<Box bg={'statusCriticalBg'} p={1}>
<InlineFeedback status="critical">
<Text color={'statusCritical'}>There is no assets setup yet for this chain.</Text>
</InlineFeedback>
</Box>
)}
{domain.currencies.length > 0 &&
(status === 'inactive' ? (
<EnableButton poolId={poolId} domain={domain} />
) : status === 'deploying' ? (
<ConnectionGuard networks={[domain.chainId]} body="Connect to the right network to continue" variant="plain">
{pool.tranches.map((t) => (
<React.Fragment key={t.id}>
{domain.canTrancheBeDeployed[t.id] && (
<DeployTrancheButton poolId={poolId} trancheId={t.id} domain={domain} onSuccess={refetch} />
)}
{domain.currencies.map((currency, i) => (
<React.Fragment key={i}>
{domain.trancheTokens[t.id] && !domain.liquidityPools[t.id][currency.address] && (
<DeployLPButton
poolId={poolId}
trancheId={t.id}
domain={domain}
currencyIndex={i}
onSuccess={refetch}
/>
)}
</React.Fragment>
))}
</React.Fragment>
))}
</ConnectionGuard>
) : (
pool.tranches.map((tranche) => (
<a href={explorer.address(domain.trancheTokens[tranche.id])} target="_blank">

Check warning on line 178 in centrifuge-app/src/pages/IssuerPool/Investors/LiquidityPools.tsx

View workflow job for this annotation

GitHub Actions / ff-prod / build-app

Using target="_blank" without rel="noreferrer" (which implies rel="noopener") is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations

Check warning on line 178 in centrifuge-app/src/pages/IssuerPool/Investors/LiquidityPools.tsx

View workflow job for this annotation

GitHub Actions / deploy-development / webapp / build-app

Using target="_blank" without rel="noreferrer" (which implies rel="noopener") is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations

Check warning on line 178 in centrifuge-app/src/pages/IssuerPool/Investors/LiquidityPools.tsx

View workflow job for this annotation

GitHub Actions / app-demo / build-app

Using target="_blank" without rel="noreferrer" (which implies rel="noopener") is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations
<Button variant="secondary" small style={{ width: '100%' }}>
<Shelf gap={1}>
<span>View {tranche.currency.symbol} token</span>
<IconExternalLink size="iconSmall" />
</Shelf>
</Button>
</a>
))
))}
</Stack>
)
}
Expand All @@ -157,14 +201,14 @@ function DeployTrancheButton({
onSuccess: () => void
}) {
const pool = usePool(poolId)
const { execute, isLoading } = useEvmTransaction(`Deploy tranche`, (cent) => cent.liquidityPools.deployTranche, {
const { execute, isLoading } = useEvmTransaction(`Deploy token`, (cent) => cent.liquidityPools.deployTranche, {
onSuccess,
})
const tranche = find(pool.tranches, (t) => t.id === trancheId)!

return (
<Button loading={isLoading} onClick={() => execute([domain.poolManager, poolId, trancheId])} small>
Deploy tranche: {tranche.currency.name}
Deploy {tranche.currency.symbol} token
</Button>
)
}
Expand All @@ -184,11 +228,9 @@ function DeployLPButton({
}) {
const pool = usePool(poolId)

const { execute, isLoading } = useEvmTransaction(
`Deploy liquidity pool`,
(cent) => cent.liquidityPools.deployLiquidityPool,
{ onSuccess }
)
const { execute, isLoading } = useEvmTransaction(`Deploy vault`, (cent) => cent.liquidityPools.deployLiquidityPool, {
onSuccess,
})
const tranche = find(pool.tranches, (t) => t.id === trancheId)!

return (
Expand All @@ -197,7 +239,7 @@ function DeployLPButton({
onClick={() => execute([domain.poolManager, poolId, trancheId, domain.currencies[currencyIndex].address])}
small
>
Deploy tranche/currency liquidity pool: {tranche.currency.name} / {domain.currencies[currencyIndex].name}
Deploy {tranche.currency.symbol} / {domain.currencies[currencyIndex].symbol} vault
</Button>
)
}
Expand Down
2 changes: 0 additions & 2 deletions centrifuge-app/src/pages/IssuerPool/Investors/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useSuitableAccounts } from '../../../utils/usePermissions'
import { IssuerPoolHeader } from '../Header'
import { InvestorStatus } from './InvestorStatus'
import { LiquidityPools } from './LiquidityPools'
import { OnboardingSettings } from './OnboardingSettings'

export function IssuerPoolInvestorsPage() {
return (
Expand All @@ -30,7 +29,6 @@ function IssuerPoolInvestors() {
<>
{canEditInvestors && <InvestorStatus />}
{isPoolAdmin && <LiquidityPools />}
{isPoolAdmin && <OnboardingSettings />}
</>
)
}
Loading

0 comments on commit 4d308e3

Please sign in to comment.