Skip to content

Commit

Permalink
Add EVM input to components
Browse files Browse the repository at this point in the history
  • Loading branch information
kattylucy committed Jul 23, 2024
1 parent 077f923 commit 902f2fc
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 48 deletions.
32 changes: 12 additions & 20 deletions centrifuge-app/src/components/PoolFees/EditFeesDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { AddFee, PoolMetadata, Rate } from '@centrifuge/centrifuge-js'
import { useCentrifugeTransaction } from '@centrifuge/centrifuge-react'
import { AddFee, PoolMetadata, Rate, evmToSubstrateAddress } from '@centrifuge/centrifuge-js'
import { useCentEvmChainId, useCentrifugeTransaction } from '@centrifuge/centrifuge-react'
import {
AddressInput,
Box,
Button,
Drawer,
Flex,
Grid,
IconButton,
IconCopy,
IconMinusCircle,
IconPlusCircle,
NumberInput,
Expand All @@ -22,11 +21,11 @@ import React from 'react'
import { useParams } from 'react-router'
import { feeCategories } from '../../config'
import { Dec } from '../../utils/Decimal'
import { copyToClipboard } from '../../utils/copyToClipboard'
import { isEvmAddress } from '../../utils/address'
import { formatPercentage } from '../../utils/formatting'
import { usePoolAdmin, useSuitableAccounts } from '../../utils/usePermissions'
import { usePool, usePoolFees, usePoolMetadata } from '../../utils/usePools'
import { combine, max, positiveNumber, required, substrateAddress } from '../../utils/validation'
import { combine, max, positiveNumber, required } from '../../utils/validation'
import { ButtonGroup } from '../ButtonGroup'

type ChargeFeesProps = {
Expand Down Expand Up @@ -54,6 +53,7 @@ export const EditFeesDrawer = ({ onClose, isOpen }: ChargeFeesProps) => {
const { data: poolMetadata, isLoading } = usePoolMetadata(pool)
const poolAdmin = usePoolAdmin(poolId)
const account = useSuitableAccounts({ poolId, poolRole: ['PoolAdmin'] })[0]
const chainId = useCentEvmChainId()

const initialFormData = React.useMemo(() => {
return poolFees
Expand Down Expand Up @@ -116,11 +116,14 @@ export const EditFeesDrawer = ({ onClose, isOpen }: ChargeFeesProps) => {
)
})
.map((fee) => {
const destination = isEvmAddress(fee.receivingAddress)
? evmToSubstrateAddress(fee.receivingAddress, chainId)
: fee.receivingAddress
return {
poolId,
fee: {
name: fee.feeName,
destination: fee.receivingAddress,
destination,
amount: Rate.fromPercent(Dec(fee?.percentOfNav || 0)),
feeId: fee.feeId,
feeType: fee.type,
Expand Down Expand Up @@ -278,24 +281,13 @@ export const EditFeesDrawer = ({ onClose, isOpen }: ChargeFeesProps) => {
</Field>
</Stack>
</Shelf>
<Field
name={`poolFees.${index}.receivingAddress`}
validate={combine(required(), substrateAddress())}
>
<Field name={`poolFees.${index}.receivingAddress`} validate={required()}>
{({ field, meta }: FieldProps) => {
return (
<TextInput
<AddressInput
{...field}
disabled={!poolAdmin || updateFeeTxLoading}
label="Receiving address"
symbol={
<IconButton
onClick={() => copyToClipboard(values.receivingAddress)}
title="Copy address to clipboard"
>
<IconCopy />
</IconButton>
}
errorMessage={(meta.touched && meta.error) || ''}
/>
)
Expand Down
11 changes: 8 additions & 3 deletions centrifuge-app/src/pages/IssuerPool/Access/AssetOriginators.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {
addressToHex,
computeTrancheId,
evmToSubstrateAddress,
getCurrencyLocation,
isSameAddress,
PoolMetadata,
TransactionOptions,
WithdrawAddress,
} from '@centrifuge/centrifuge-js'
import {
useCentEvmChainId,
useCentrifuge,
useCentrifugeApi,
useCentrifugeConsts,
Expand Down Expand Up @@ -118,6 +120,7 @@ function AOForm({
poolId: string
}) {
const [isEditing, setIsEditing] = React.useState(false)
const chainId = useCentEvmChainId()
const [account] = useSuitableAccounts({ poolId, actingAddress: [ao.address] }).filter((a) => a.proxies?.length === 2)
const identity = useIdentity(ao.address)
const api = useCentrifugeApi()
Expand Down Expand Up @@ -311,8 +314,8 @@ function AOForm({
}
execute(
[
addedWithdraw.map((w) => getKeyForReceiver(api, w)),
removedWithdraw.map((w) => getKeyForReceiver(api, w)),
addedWithdraw.filter((w) => Object.keys(w).length !== 0).map((w) => getKeyForReceiver(api, w)),
removedWithdraw.filter((w) => Object.keys(w).length !== 0).map((w) => getKeyForReceiver(api, w)),
null,
addedPermissions,
addedDelegates,
Expand Down Expand Up @@ -438,7 +441,9 @@ function AOForm({
<AddAddressInput
existingAddresses={[...form.values.delegates, ao.address]}
onAdd={(address) => {
fldArr.push(addressToHex(address))
fldArr.push(
isEvmAddress(address) ? evmToSubstrateAddress(address, chainId ?? 0) : addressToHex(address)
)
}}
/>
)}
Expand Down
8 changes: 6 additions & 2 deletions centrifuge-app/src/pages/IssuerPool/Access/MultisigForm.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { addressToHex } from '@centrifuge/centrifuge-js'
import { evmToSubstrateAddress } from '@centrifuge/centrifuge-js'
import { useCentEvmChainId } from '@centrifuge/centrifuge-react'
import { Button, IconMinusCircle, Stack, Text } from '@centrifuge/fabric'
import { FieldArray, useFormikContext } from 'formik'
import * as React from 'react'
import { DataTable } from '../../../components/DataTable'
import { Identity } from '../../../components/Identity'
import { isEvmAddress } from '../../../utils/address'
import { AddAddressInput } from '../Configuration/AddAddressInput'
import { ChangeThreshold } from './ChangeTreshold'
import type { PoolManagersInput } from './PoolManagers'

type Row = { address: string; index: number }
type Props = { isEditing?: boolean; isLoading?: boolean; canRemoveFirst?: boolean }

export function MultisigForm({ isEditing = true, canRemoveFirst = true, isLoading }: Props) {
const chainId = useCentEvmChainId()
const form = useFormikContext<PoolManagersInput>()
const { adminMultisig } = form.values
const rows = React.useMemo(
Expand Down Expand Up @@ -66,7 +70,7 @@ export function MultisigForm({ isEditing = true, canRemoveFirst = true, isLoadin
if (adminMultisig.signers.length === 1) {
form.setFieldValue('adminMultisig.threshold', 2, false)
}
fldArr.push(addressToHex(address))
fldArr.push(isEvmAddress(address) ? evmToSubstrateAddress(address, chainId ?? 0) : address)
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isSameAddress } from '@centrifuge/centrifuge-js'
import { addressToHex, isSameAddress } from '@centrifuge/centrifuge-js'
import { useCentrifugeUtils } from '@centrifuge/centrifuge-react'
import { Button, Grid, SearchInput, Shelf, Text } from '@centrifuge/fabric'
import { AddressInput, Button, Grid, Shelf, Text } from '@centrifuge/fabric'
import Identicon from '@polkadot/react-identicon'
import { useState } from 'react'
import { truncate } from '../../../utils/web3'
Expand All @@ -15,26 +15,40 @@ export function AddAddressInput({
const [address, setAddress] = useState('')

const utils = useCentrifugeUtils()
let truncated
let truncated: string | undefined
try {
truncated = truncate(utils.formatAddress(address))
} catch (e) {
//
truncated = undefined
}

const exists = !!truncated && existingAddresses.some((addr) => isSameAddress(addr, address))

function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const newAddress = e.target.value
setAddress(newAddress)
}

function handleBlur(e: React.FocusEvent<HTMLInputElement>) {
const address = e.target.value
if (truncated) {
onAdd(addressToHex(address))
setAddress('')
}
}

return (
<Grid columns={2} equalColumns gap={4} alignItems="center">
<SearchInput
name="search"
<AddressInput
clearIcon
placeholder="Search to add address..."
value={address}
onChange={(e) => setAddress(e.target.value)}
onChange={handleChange}
onBlur={handleBlur}
/>
{address &&
(truncated ? (
<Shelf gap={2}>
<Shelf gap={2} alignItems="center">
<Shelf style={{ pointerEvents: 'none' }} gap="4px">
<Identicon value={address} size={16} theme="polkadot" />
<Text variant="label2" color="textPrimary">
Expand All @@ -44,7 +58,7 @@ export function AddAddressInput({
<Button
variant="secondary"
onClick={() => {
onAdd(address)
onAdd(addressToHex(address))
setAddress('')
}}
small
Expand Down
13 changes: 6 additions & 7 deletions centrifuge-app/src/pages/IssuerPool/Investors/InvestorStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import {
useWallet,
} from '@centrifuge/centrifuge-react'
import {
AddressInput,
Button,
Grid,
IconAlertCircle,
IconCheckCircle,
IconInfoFailed,
IconMinus,
IconPlus,
SearchInput,
Select,
Shelf,
Stack,
Expand Down Expand Up @@ -95,19 +95,18 @@ export function InvestorStatus() {
setPendingTrancheId(trancheId)
}

function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
setAddress(e.target.value)
}

return (
<PageSection
title="Investor status"
subtitle="Display investor status, and add or remove from investor memberlist."
>
<Stack gap={2}>
<Grid columns={2} gap={2} alignItems="center">
<SearchInput
name="investorStatus"
value={address}
onChange={(e) => setAddress(e.target.value)}
placeholder="Enter address..."
/>
<AddressInput label="" placeholder="Add an address" onChange={handleChange} value={address} />
<Select
value={chain}
options={[
Expand Down
2 changes: 2 additions & 0 deletions centrifuge-js/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ export function computeMultisig(multisig: Multisig): ComputedMultisig {
}

export function evmToSubstrateAddress(address: string, chainId: number) {
if (!chainId) return

// Bytes EVM\0 as suffix
const suffix = '45564d00'
const chainHex = Number(chainId).toString(16).padStart(16, '0')
Expand Down
22 changes: 15 additions & 7 deletions fabric/src/components/TextInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,10 @@ export function TextAreaInput({
}

export type AddressInputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value'> &
Omit<InputUnitProps, 'inputElement'>
Omit<InputUnitProps, 'inputElement'> & {
value?: string
clearIcon?: boolean
}

export function AddressInput({
id,
Expand All @@ -262,40 +265,44 @@ export function AddressInput({
errorMessage,
onBlur,
onChange,
value = '',
clearIcon,
...inputProps
}: AddressInputProps) {
const defaultId = React.useId()
id ??= defaultId

const [network, setNetwork] = React.useState<'ethereum' | 'centrifuge' | 'loading' | null>(null)

function handleChange(e: React.FocusEvent<HTMLInputElement>) {
const address = e.target.value
if (isEvmAddress(address) && address.length > 3) {
React.useEffect(() => {
if (isEvmAddress(value) && value.length > 3) {
setNetwork('ethereum')
} else if (isSubstrateAddress(address) && address.length > 3) {
} else if (isSubstrateAddress(value) && value.length > 3) {
setNetwork('centrifuge')
} else if (address !== '') {
} else if (value !== '') {
setNetwork('loading')
} else {
setNetwork(null)
}
}, [value])

function handleChange(e: React.FocusEvent<HTMLInputElement>) {
if (onChange) {
onChange(e)
}
}

function handleBlur(e: React.FocusEvent<HTMLInputElement>) {
const address = e.target.value
if (!(isSubstrateAddress(address) || isEvmAddress(address))) {
if (!(isSubstrateAddress(address) || isEvmAddress(address)) || clearIcon) {
setNetwork(null)
}

if (onBlur) {
onBlur(e)
}
}

return (
<InputUnit
label={label}
Expand All @@ -308,6 +315,7 @@ export function AddressInput({
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={value}
action={
network && (
<Shelf
Expand Down

0 comments on commit 902f2fc

Please sign in to comment.