polkadot-js/apps

View on GitHub
packages/react-components/src/AccountSidebar/RegistrarJudgement.tsx

Summary

Maintainability
A
25 mins
Test Coverage
// Copyright 2017-2024 @polkadot/react-query authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { Bytes, Option } from '@polkadot/types';
import type { PalletIdentityRegistration } from '@polkadot/types/lookup';
import type { ITuple } from '@polkadot/types/types';
import type { HexString } from '@polkadot/util/types';

import React, { useEffect, useState } from 'react';

import { useApi, useCall } from '@polkadot/react-hooks';

import Dropdown from '../Dropdown.js';
import Input from '../Input.js';
import InputAddress from '../InputAddress/index.js';
import MarkError from '../MarkError.js';
import Modal from '../Modal/index.js';
import Spinner from '../Spinner.js';
import { useTranslation } from '../translate.js';
import TxButton from '../TxButton.js';

interface Props {
  address: string;
  registrars: { address: string; index: number }[];
  toggleJudgement: () => void;
}

const JUDGEMENT_ENUM = [
  { text: 'Unknown', value: 0 },
  { text: 'Fee paid', value: 1 },
  { text: 'Reasonable', value: 2 },
  { text: 'Known good', value: 3 },
  { text: 'Out of date', value: 4 },
  { text: 'Low quality', value: 5 }
];

const OPT_ID = {
  transform: (optId: Option<ITuple<[PalletIdentityRegistration, Option<Bytes>]>>): HexString | null => {
    const id = optId.isSome
      ? optId.unwrap()
      : null;

    // Backwards compatibility - https://github.com/polkadot-js/apps/issues/10493
    return !id
      ? null
      : Array.isArray(id)
        ? id[0].info.hash.toHex()
        : (id as unknown as PalletIdentityRegistration).info.hash.toHex();
  }
};

function RegistrarJudgement ({ address, registrars, toggleJudgement }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();
  const { apiIdentity, enableIdentity } = useApi();
  const identityHash = useCall(apiIdentity.query.identity.identityOf, [address], OPT_ID);
  const [addresses] = useState(() => registrars.map(({ address }) => address));
  const [judgementAccountId, setJudgementAccountId] = useState<string | null>(null);
  const [judgementEnum, setJudgementEnum] = useState(2); // Reasonable
  const [registrarIndex, setRegistrarIndex] = useState(-1);

  // find the id of our registrar in the list
  useEffect((): void => {
    const registrar = registrars.find(({ address }) => judgementAccountId === address);

    setRegistrarIndex(
      registrar
        ? registrar.index
        : -1
    );
  }, [judgementAccountId, registrars]);

  return (
    <Modal
      header={t('Provide judgement')}
      onClose={toggleJudgement}
      size='small'
    >
      <Modal.Content>
        <InputAddress
          filter={addresses}
          label={t('registrar account')}
          onChange={setJudgementAccountId}
          type='account'
        />
        <Input
          isDisabled
          label={t('registrar index')}
          value={registrarIndex === -1 ? t('invalid/unknown registrar account') : registrarIndex.toString()}
        />
        <Dropdown
          label={t('judgement')}
          onChange={setJudgementEnum}
          options={JUDGEMENT_ENUM}
          value={judgementEnum}
        />
        {identityHash
          ? (
            <Input
              defaultValue={identityHash}
              isDisabled
              label={t('identity hash')}
            />
          )
          : identityHash === null
            ? <MarkError content={t('No identity associated with account')} />
            : <Spinner noLabel />
        }
      </Modal.Content>
      <Modal.Actions>
        <TxButton
          accountId={judgementAccountId}
          icon='check'
          isDisabled={!enableIdentity || !identityHash || registrarIndex === -1}
          label={t('Judge')}
          onStart={toggleJudgement}
          params={
            apiIdentity.tx.identity.provideJudgement.meta.args.length === 4
              ? [registrarIndex, address, judgementEnum, identityHash]
              : [registrarIndex, address, judgementEnum]
          }
          tx={apiIdentity.tx.identity.provideJudgement}
        />
      </Modal.Actions>
    </Modal>
  );
}

export default React.memo(RegistrarJudgement);