Skip to content

Commit

Permalink
Centrifuge App: Liquidity pools investments (#1542)
Browse files Browse the repository at this point in the history
  • Loading branch information
onnovisser authored Oct 30, 2023
1 parent 957418e commit 3ae0643
Show file tree
Hide file tree
Showing 62 changed files with 2,667 additions and 481 deletions.
2 changes: 1 addition & 1 deletion centrifuge-app/.env-config/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ REACT_APP_WHITELISTED_ACCOUNTS=
REACT_APP_TINLAKE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_clhi43ef5g4rw49zwftsvd2ks/subgraphs/main/1.0.2/gn
REACT_APP_REWARDS_TREE_URL=https://storage.googleapis.com/rad-rewards-trees-kovan-staging/latest.json
REACT_APP_WALLETCONNECT_ID=c32fa79350803519804a67fcab0b742a
REACT_APP_MEMBERLIST_ADMIN_PURE_PROXY=kAJ27w29x7gHM75xajP2yXVLjVBaKmmUTxHwgRuCoAcWaoEiz
REACT_APP_MEMBERLIST_ADMIN_PURE_PROXY=kAJ27w29x7gHM75xajP2yXVLjVBaKmmUTxHwgRuCoAcWaoEiz
214 changes: 214 additions & 0 deletions centrifuge-app/src/components/DebugFlags/components/ConvertAddress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { addressToHex } from '@centrifuge/centrifuge-js'
import {
getChainInfo,
truncateAddress,
useCentrifugeApi,
useCentrifugeUtils,
useWallet,
} from '@centrifuge/centrifuge-react'
import { Dialog, Grid, Select, Stack, Text, TextInput } from '@centrifuge/fabric'
import { isAddress as isEvmAddress } from '@ethersproject/address'
import { isAddress as isSubstrateAddress } from '@polkadot/util-crypto'
import * as React from 'react'
import { useQuery } from 'react-query'
import { firstValueFrom } from 'rxjs'
import { copyToClipboard } from '../../../utils/copyToClipboard'

enum LocationType {
Parachain = 'Parachain',
Relaychain = 'Relaychain',
Native = 'Native',
EVM = 'EVM',
}

export function ConvertAddress() {
const [open, setOpen] = React.useState(false)
const {
evm: { accounts: evmAccounts, chains },
substrate: { accounts: substrateAccounts },
} = useWallet()

const [address, setAddress] = React.useState('')
const [locationType, setLocationType] = React.useState<LocationType>(LocationType.Parachain)
const [locationDetail, setLocationDetail] = React.useState('')
const utils = useCentrifugeUtils()
const api = useCentrifugeApi()
const addressListId = React.useId()
const locationListId = React.useId()
const isValidAddress =
locationType === LocationType.EVM
? isEvmAddress(address)
: locationType === LocationType.Parachain
? isSubstrateAddress(address) || isEvmAddress(address)
: !isEvmAddress(address) && isSubstrateAddress(address)

function getMultilocation() {
if (!isValidAddress) return null
switch (locationType) {
case LocationType.Parachain:
if (!locationDetail) return null
return {
parents: 1,
interior: {
X2: [
{
Parachain: locationDetail,
},
isEvmAddress(address)
? {
AccountKey20: {
network: null,
key: address,
},
}
: {
AccountId32: {
id: addressToHex(address),
},
},
],
},
}
case LocationType.Relaychain:
return {
parents: 1,
interior: {
X1: {
AccountId32: {
id: addressToHex(address),
},
},
},
}
case LocationType.Native:
return {}
case LocationType.EVM:
if (!locationDetail) return null
return {
parents: 0,
interior: {
X1: {
AccountKey20: {
network: { Ethereum: { chainId: locationDetail } },
key: address,
},
},
},
}
}
}

const multilocation = getMultilocation()

const { data: convertedAddress } = useQuery(
[address, locationType, locationDetail],
async () => {
if (locationType === LocationType.Native) return address
const addr = await firstValueFrom(api.call.accountConversionApi.conversionOf(multilocation))
return addr.toHuman() as string
},
{
enabled: !!address && !!multilocation && isValidAddress,
staleTime: Infinity,
}
)

return (
<>
<button onClick={() => setOpen(true)}>Convert address</button>
<Dialog title="Convert address" width="800px" isOpen={open} onClose={() => setOpen(false)}>
<Stack gap={4}>
<Stack gap={1}>
<datalist id={addressListId}>
{evmAccounts?.map((addr) => (
<option value={addr}>{truncateAddress(addr)} (EVM)</option>
))}
{substrateAccounts?.map((acc) => (
<option value={utils.formatAddress(acc.address)}>
{acc.name && `${acc.name} - `}
{truncateAddress(utils.formatAddress(acc.address))}
</option>
))}
</datalist>
<Select
label="From"
value={locationType}
options={[
{ label: 'Parachain', value: LocationType.Parachain },
{ label: 'Relaychain', value: LocationType.Relaychain },
{ label: 'Native', value: LocationType.Native },
{ label: 'EVM', value: LocationType.EVM },
]}
onChange={(e) => {
setLocationType(e.target.value as any)
}}
/>
{locationType === LocationType.EVM ? (
<>
<TextInput
label="EVM chain ID"
value={locationDetail}
onChange={(e) => setLocationDetail(e.target.value)}
list={locationListId}
/>
<datalist id={locationListId}>
{Object.keys(chains).map((chainId) => (
<option value={chainId}>
{chainId} - {getChainInfo(chains, Number(chainId)).name}
</option>
))}
</datalist>
</>
) : locationType === LocationType.Parachain ? (
<>
<TextInput
label="Para ID"
value={locationDetail}
onChange={(e) => setLocationDetail(e.target.value)}
list={locationListId}
/>
<datalist id={locationListId}></datalist>
</>
) : null}

<TextInput
label={
locationType === LocationType.EVM
? 'EVM address'
: locationType === LocationType.Parachain
? 'Substrate or EVM address'
: 'Substrate address'
}
value={address}
onChange={(e) => setAddress(e.target.value)}
list={addressListId}
errorMessage={address && !isValidAddress ? 'Invalid address' : ''}
/>
</Stack>
{convertedAddress && (
<Stack gap={2}>
<Text variant="heading3">Converted address</Text>
<Grid columns={2} gap={1}>
<Text variant="label1">ss58</Text>
<Text
style={{ wordBreak: 'break-all', cursor: 'copy' }}
onClick={() => copyToClipboard(utils.formatAddress(convertedAddress))}
>
{utils.formatAddress(convertedAddress)}
</Text>

<Text variant="label1">hex</Text>
<Text
style={{ wordBreak: 'break-all', cursor: 'copy' }}
onClick={() => copyToClipboard(addressToHex(convertedAddress))}
>
{addressToHex(convertedAddress)}
</Text>
</Grid>
</Stack>
)}
</Stack>
</Dialog>
</>
)
}

This file was deleted.

33 changes: 27 additions & 6 deletions centrifuge-app/src/components/DebugFlags/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { config } from '../../config'
import { ConvertEvmAddress } from './components/ConvertEvmAddress'
import { config, isTestEnv } from '../../config'
import { ConvertAddress } from './components/ConvertAddress'

const params = new URLSearchParams(typeof window !== 'undefined' ? window.location.search : {})
export const debug =
Expand Down Expand Up @@ -36,6 +36,7 @@ export type Key =
| 'batchMintNFTs'
| 'persistDebugFlags'
| 'showBase'
| 'showArbitrum'
| 'showUnusedFlags'
| 'allowInvestBelowMin'
| 'alternativeTheme'
Expand All @@ -45,8 +46,11 @@ export type Key =
| 'showAdvancedAccounts'
| 'editAdminConfig'
| 'showPodAccountCreation'
| 'convertEvmAddress'
| 'convertAddress'
| 'showPortfolio'
| 'showTestNets'
| 'showSwaps'
| 'showLiquidityPoolsOptions'
| 'showPrime'
| 'poolCreationType'

Expand Down Expand Up @@ -77,6 +81,16 @@ export const flagsConfig: Record<Key, DebugFlagConfig> = {
default: false,
alwaysShow: true,
},
showArbitrum: {
type: 'checkbox',
default: false,
alwaysShow: true,
},
showTestNets: {
type: 'checkbox',
default: isTestEnv,
alwaysShow: true,
},
editPoolConfig: {
type: 'checkbox',
default: false,
Expand All @@ -85,6 +99,10 @@ export const flagsConfig: Record<Key, DebugFlagConfig> = {
type: 'checkbox',
default: false,
},
showLiquidityPoolsOptions: {
type: 'checkbox',
default: false,
},
poolReporting: {
type: 'checkbox',
default: false,
Expand All @@ -111,16 +129,19 @@ export const flagsConfig: Record<Key, DebugFlagConfig> = {
default: false,
alwaysShow: true,
},
convertEvmAddress: {
convertAddress: {
type: 'component',
Component: ConvertEvmAddress,
Component: ConvertAddress,
default: null,
alwaysShow: true,
},
showPortfolio: {
type: 'checkbox',
default: false,
alwaysShow: true,
},
showSwaps: {
type: 'checkbox',
default: false,
},
showPrime: {
type: 'checkbox',
Expand Down
Loading

0 comments on commit 3ae0643

Please sign in to comment.