Skip to content

Commit

Permalink
check for funds on the ppl chain and add warning and info
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut committed Feb 25, 2025
1 parent 12e85c1 commit 697e4ed
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 127 deletions.
19 changes: 10 additions & 9 deletions packages/ui/src/components/EasySetup/BalancesTransfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export const BalancesTransfer = ({ className, onSetExtrinsic, onSetErrorMessage,
}, [fieldInfoMap])
const { hasEnoughFreeBalance: hasEnoughNativeToken } = useCheckBalance({
min: totalPerAsset[0],
address: from
address: from,
withPplApi: false
})

const assetList = useMemo(() => {
Expand Down Expand Up @@ -89,12 +90,12 @@ export const BalancesTransfer = ({ className, onSetExtrinsic, onSetErrorMessage,
// check for the native asset
useEffect(() => {
if (!!totalPerAsset[0] && !hasEnoughNativeToken) {
const message = getErrorMessageReservedFunds(
'"From" address',
formatBigIntBalance(totalPerAsset[0], chainInfo?.tokenDecimals, {
const message = getErrorMessageReservedFunds({
identifier: '"From" address',
requiredBalanceString: formatBigIntBalance(totalPerAsset[0], chainInfo?.tokenDecimals, {
tokenSymbol: chainInfo?.tokenSymbol
})
)
})
onSetErrorMessage(message)
}
}, [chainInfo, hasEnoughNativeToken, onSetErrorMessage, totalPerAsset])
Expand All @@ -108,12 +109,12 @@ export const BalancesTransfer = ({ className, onSetExtrinsic, onSetErrorMessage,
const asset = assetList.find((asset) => asset.id === Number(assetIssue?.[0]))

if (assetIssue) {
const message = getErrorMessageReservedFunds(
'"From" address',
formatBigIntBalance(assetIssue[1], asset?.decimals, {
const message = getErrorMessageReservedFunds({
identifier: '"From" address',
requiredBalanceString: formatBigIntBalance(assetIssue[1], asset?.decimals, {
tokenSymbol: asset?.symbol
})
)
})
onSetErrorMessage(message)
}
}, [assetList, balances, chainInfo, hasEnoughNativeToken, onSetErrorMessage, totalPerAsset])
Expand Down
34 changes: 24 additions & 10 deletions packages/ui/src/components/EasySetup/SetIdentity.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Grid2 as Grid } from '@mui/material'
import { Alert, Grid2 as Grid } from '@mui/material'
import { styled } from '@mui/material/styles'
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
import { TextField } from '../library'
Expand Down Expand Up @@ -133,10 +133,10 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
}, [identityFields])

const { reserved: identityReservedFunds } = useSetIdentityReservedFunds(identityFields)

const { hasEnoughFreeBalance: hasOriginEnoughFunds } = useCheckBalance({
min: identityReservedFunds,
address: from
address: from,
withPplApi: true
})

useEffect(() => {
Expand Down Expand Up @@ -164,11 +164,12 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
const reservedString = formatBigIntBalance(identityReservedFunds, chainInfo?.tokenDecimals, {
tokenSymbol: chainInfo?.tokenSymbol
})
const errorWithReservedFunds = getErrorMessageReservedFunds(
'"From" account',
const errorWithReservedFunds = getErrorMessageReservedFunds({
identifier: '"From" account',
requiredBalanceString,
reservedString
)
reservedString,
withPpleChain: true
})

onSetErrorMessage(errorWithReservedFunds)
return
Expand Down Expand Up @@ -249,6 +250,16 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
spacing={1}
data-cy="section-set-identity"
>
<Grid size={{ xs: 12 }}>
<AlertStyled
className={className}
severity="info"
data-cy="alert-info-identity"
>
Identity is managed on the People Chain. You need both the signatories, and the multisig
to have funds on this chain.
</AlertStyled>
</Grid>
{identityFields &&
Object.entries(identityFields).map(([fieldName, value]) => {
const { field, placeholder, required } = fieldNameAndPlaceholder(
Expand Down Expand Up @@ -286,12 +297,15 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
)
}

const AlertStyled = styled(Alert)`
border: 0;
margin-bottom: 0.5rem;
`

const TextFieldStyled = styled(TextField)`
.MuiFormHelperText-root.Mui-error {
position: initial;
}
`

export default styled(SetIdentity)`
margin-top: 0.5rem;
`
export default styled(SetIdentity)``
6 changes: 4 additions & 2 deletions packages/ui/src/components/modals/ChangeMultisig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ const ChangeMultisig = ({ onClose, className }: Props) => {
const { proxyAdditionNeededFunds } = useProxyAdditionNeededFunds()
const { hasEnoughFreeBalance: hasProxyEnoughFunds } = useCheckBalance({
min: proxyAdditionNeededFunds,
address: selectedMultiProxy?.proxy
address: selectedMultiProxy?.proxy,
withPplApi: false
})
const multisigList = useMemo(() => getMultisigAsAccountBaseInfo(), [getMultisigAsAccountBaseInfo])
const [callError, setCallError] = useState('')
Expand Down Expand Up @@ -316,7 +317,8 @@ const ChangeMultisig = ({ onClose, className }: Props) => {
)
const { hasEnoughFreeBalance: hasSignerEnoughFunds } = useCheckBalance({
min: neededBalance,
address: selectedAccount?.address
address: selectedAccount?.address,
withPplApi: false
})

useEffect(() => {
Expand Down
19 changes: 6 additions & 13 deletions packages/ui/src/components/modals/ProposalSigning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { Button, TextField } from '../library'
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react'
import { styled } from '@mui/material/styles'
import { useAccounts } from '../../contexts/AccountsContext'
import { useApi } from '../../contexts/ApiContext'
import { useMultiProxy } from '../../contexts/MultiProxyContext'
import CallInfo from '../CallInfo'
import SignerSelection from '../select/SignerSelection'
Expand All @@ -25,7 +24,7 @@ import { getAsMultiTx } from '../../utils/getAsMultiTx'
import { CallDataInfoFromChain } from '../../hooks/usePendingTx'
import { debounce } from '../../utils/debounce'
import { FixedSizeBinary, HexString, Transaction } from 'polkadot-api'
import { usePplApi } from '../../contexts/PeopleChainApiContext'
import { useAnyApi } from '../../hooks/useAnyApi'

export interface SigningModalProps {
onClose: () => void
Expand All @@ -44,13 +43,7 @@ const ProposalSigning = ({
onSuccess,
isPplChainTx
}: SigningModalProps) => {
const { api: normalApi, compatibilityToken: normalCompatibilityToken } = useApi()
const { pplApi, pplCompatibilityToken } = usePplApi()
const api = useMemo(() => (isPplChainTx ? pplApi : normalApi), [isPplChainTx, normalApi, pplApi])
const compatibilityToken = useMemo(
() => (isPplChainTx ? pplCompatibilityToken : normalCompatibilityToken),
[isPplChainTx, normalCompatibilityToken, pplCompatibilityToken]
)
const { api, compatibilityToken } = useAnyApi({ withPplApi: isPplChainTx })
const [isSubmitting, setIsSubmitting] = useState(false)
const { getMultisigByAddress, setRefetchMultisigTimeoutMinutes } = useMultiProxy()
const { selectedAccount } = useAccounts()
Expand All @@ -73,7 +66,8 @@ const ProposalSigning = ({
)
const { hasEnoughFreeBalance: hasSignerEnoughFunds } = useCheckBalance({
min: 0n,
address: selectedAccount?.address
address: selectedAccount?.address,
withPplApi: isPplChainTx
})

const hasReachedThreshold = useMemo(
Expand Down Expand Up @@ -136,9 +130,9 @@ const ProposalSigning = ({
}

setErrorMessage(
"The selected signer doesn't have enough funds to pay for the transaction fees."
`The selected signer doesn't have enough funds ${isPplChainTx ? 'on the People Chain ' : ''}to pay for the transaction fees.`
)
}, [hasSignerEnoughFunds])
}, [hasSignerEnoughFunds, isPplChainTx])

const onSign = useCallback(
async (isApproving: boolean) => {
Expand Down Expand Up @@ -225,7 +219,6 @@ const ProposalSigning = ({
setIsSubmitting(true)
let tx: Transaction<any, any, any, any> | undefined

console.log('proposalData', proposalData)
// if it's a rejection we can send it right away, no need for weight or calldata
if (!isApproving) {
tx = api.tx.Multisig.cancel_as_multi({
Expand Down
38 changes: 19 additions & 19 deletions packages/ui/src/components/modals/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Button, ButtonWithIcon, Select } from '../library'
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
import { styled } from '@mui/material/styles'
import { useAccounts } from '../../contexts/AccountsContext'
import { useApi } from '../../contexts/ApiContext'
import { useMultiProxy } from '../../contexts/MultiProxyContext'
import SignerSelection from '../select/SignerSelection'
import { useSigningCallback } from '../../hooks/useSigningCallback'
Expand All @@ -28,6 +27,7 @@ import SetIdentity from '../EasySetup/SetIdentity'
import { getErrorMessageReservedFunds } from '../../utils/getErrorMessageReservedFunds'
import { Transaction } from 'polkadot-api'
import { useHasIdentityFeature } from '../../hooks/useHasIdentityFeature'
import { useAnyApi } from '../../hooks/useAnyApi'

export enum EasyTransferTitle {
SendTokens = 'Send tokens',
Expand All @@ -47,7 +47,6 @@ interface Props {
}

const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props) => {
const { api, chainInfo } = useApi()
const [isSubmitting, setIsSubmitting] = useState(false)
const {
selectedMultiProxy,
Expand Down Expand Up @@ -87,8 +86,14 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
const [selectedEasyOption, setSelectedEasyOption] = useState<EasyTransferTitle>(
preselected || DEFAULT_EASY_SETUP_SELECTION
)
const withPplApi = useMemo(
() => selectedEasyOption === EasyTransferTitle.SetIdentity,
[selectedEasyOption]
)
const { chainInfo } = useAnyApi({ withPplApi })

// this is a creation so we can force the asMulti
// this is a tx creation and not the signature of an existing tx
// so we can force the asMulti
const multisigTx = useGetMultisigTx({
selectedMultisig,
extrinsicToCall,
Expand All @@ -97,19 +102,20 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
fromAddress: selectedOrigin.address,
threshold,
forceAsMulti: true,
withPplApi: selectedEasyOption === EasyTransferTitle.SetIdentity
withPplApi
})

const { multisigProposalNeededFunds, reserved } = useMultisigProposalNeededFunds({
threshold,
signatories: selectedMultisig?.signatories,
call: multisigTx,
withPplApi: selectedEasyOption === EasyTransferTitle.SetIdentity
withPplApi
})

const { hasEnoughFreeBalance: hasSignerEnoughFunds } = useCheckBalance({
min: multisigProposalNeededFunds,
address: selectedAccount?.address
address: selectedAccount?.address,
withPplApi
})

useEffect(() => {
Expand All @@ -123,14 +129,15 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
const reservedString = formatBigIntBalance(reserved, chainInfo?.tokenDecimals, {
tokenSymbol: chainInfo?.tokenSymbol
})
const errorWithReservedFunds = getErrorMessageReservedFunds(
'"Signing with" account',
const errorWithReservedFunds = getErrorMessageReservedFunds({
identifier: '"Signing with" account',
requiredBalanceString,
reservedString
)
reservedString,
withPpleChain: withPplApi
})
setErrorMessage(errorWithReservedFunds)
}
}, [chainInfo, reserved, hasSignerEnoughFunds, multisigProposalNeededFunds])
}, [chainInfo, reserved, hasSignerEnoughFunds, multisigProposalNeededFunds, withPplApi])

const onSubmitting = useCallback(() => {
setIsSubmitting(false)
Expand Down Expand Up @@ -216,13 +223,6 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
return
}

if (!api) {
const error = 'Api is not ready'
console.error(error)
setErrorMessage(error)
return
}

if (!selectedAccount || !selectedOrigin) {
const error = 'No selected account or multisig/proxy'
console.error(error)
Expand All @@ -246,7 +246,7 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
multisigTx
.signSubmitAndWatch(selectedAccount.polkadotSigner, { at: 'best' })
.subscribe(signCallback)
}, [threshold, api, selectedOrigin, extrinsicToCall, multisigTx, selectedAccount, signCallback])
}, [threshold, selectedOrigin, extrinsicToCall, multisigTx, selectedAccount, signCallback])

const onChangeEasySetupOption: (event: SelectChangeEvent<unknown>) => void = useCallback(
({ target: { value } }) => {
Expand Down
9 changes: 5 additions & 4 deletions packages/ui/src/components/modals/WalletConnectSigning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ const ProposalSigning = ({ onClose, className, request, onSuccess }: SigningModa
})
const { hasEnoughFreeBalance: hasSignerEnoughFunds } = useCheckBalance({
min: multisigProposalNeededFunds,
address: selectedAccount?.address
address: selectedAccount?.address,
withPplApi: false
})

useEffect(() => {
Expand Down Expand Up @@ -120,11 +121,11 @@ const ProposalSigning = ({ onClose, className, request, onSuccess }: SigningModa
const reservedString = formatBigIntBalance(reserved, chainInfo?.tokenDecimals, {
tokenSymbol: chainInfo?.tokenSymbol
})
const errorWithReservedFunds = getErrorMessageReservedFunds(
'"Signing with" account',
const errorWithReservedFunds = getErrorMessageReservedFunds({
identifier: '"Signing with" account',
requiredBalanceString,
reservedString
)
})
setErrorMessage(errorWithReservedFunds)
}
}, [chainInfo, reserved, hasSignerEnoughFunds, multisigProposalNeededFunds])
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/src/contexts/ApiContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export const isContextOf = <Id extends ApiDescriptors>(
}

export const isContextIn = <Id extends ApiDescriptors, Ids extends ApiDescriptors[] = Id[]>(
api: unknown,
ctx: unknown,
descriptors: Id[]
): api is IApiContext<Ids[number]> => {
return descriptors.some((descriptor) => isContextOf(api, descriptor))
): ctx is IApiContext<Ids[number]> => {
return descriptors.some((descriptor) => isContextOf(ctx, descriptor))
}

export interface ChainInfoHuman {
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/src/contexts/PeopleChainApiContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ export const isPplContextIn = <
Id extends PplDescriptorKeys,
Ids extends PplDescriptorKeys[] = Id[]
>(
api: unknown,
ctx: unknown,
descriptors: Id[]
): api is IPplApiContext<Ids[number]> => {
return descriptors.some((descriptor) => isPplContextOf(api, descriptor))
): ctx is IPplApiContext<Ids[number]> => {
return descriptors.some((descriptor) => isPplContextOf(ctx, descriptor))
}

const PplApiContext = createContext<IPplApiContext<PplDescriptorKeys> | undefined>(undefined)
Expand Down
35 changes: 35 additions & 0 deletions packages/ui/src/hooks/useAnyApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useMemo } from 'react'
import { useApi } from '../contexts/ApiContext'
import { usePplApi } from '../contexts/PeopleChainApiContext'

interface Props {
withPplApi: boolean
}

export const useAnyApi = ({ withPplApi }: Props) => {
const normalCtx = useApi()
const {
api: normalApi,
compatibilityToken: normalCompatibilityToken,
chainInfo: normalChainInfo,
client: normalClient
} = normalCtx
const pplCtx = usePplApi()
const { pplApi, pplCompatibilityToken, pplChainInfo, pplClient } = pplCtx

const api = useMemo(() => (withPplApi ? pplApi : normalApi), [withPplApi, normalApi, pplApi])
const compatibilityToken = useMemo(
() => (withPplApi ? pplCompatibilityToken : normalCompatibilityToken),
[withPplApi, normalCompatibilityToken, pplCompatibilityToken]
)
const chainInfo = useMemo(
() => (withPplApi ? pplChainInfo : normalChainInfo),
[withPplApi, normalChainInfo, pplChainInfo]
)
const client = useMemo(
() => (withPplApi ? pplClient : normalClient),
[withPplApi, normalClient, pplClient]
)

return { api, compatibilityToken, chainInfo, client }
}
Loading

0 comments on commit 697e4ed

Please sign in to comment.