// Copyright 2019-2023 @polkadot/extension-ui authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { AccountJson, RequestSign } from '@polkadot/extension-base/background/types'; import type { ExtrinsicPayload } from '@polkadot/types/interfaces'; import type { SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types'; import type { HexString } from '@polkadot/util/types'; import React, { useCallback, useContext, useEffect, useState } from 'react'; import { TypeRegistry } from '@polkadot/types'; import { ActionContext, Address, VerticalSpace, Warning } from '../../../components/index.js'; import { approveSignSignature } from '../../../messaging.js'; import { useTranslation } from '../../../translate.js'; import Bytes from '../Bytes.js'; import Extrinsic from '../Extrinsic.js'; import LedgerSign from '../LedgerSign.js'; import Qr from '../Qr.js'; import SignArea from './SignArea.js'; interface Props { account: AccountJson; buttonText: string; isFirst: boolean; request: RequestSign; signId: string; url: string; } interface Data { hexBytes: string | null; payload: ExtrinsicPayload | null; } export const CMD_MORTAL = 2; export const CMD_SIGN_MESSAGE = 3; // keep it global, we can and will re-use this across requests const registry = new TypeRegistry(); function isRawPayload (payload: SignerPayloadJSON | SignerPayloadRaw): payload is SignerPayloadRaw { return !!(payload as SignerPayloadRaw).data; } export default function Request ({ account: { accountIndex, addressOffset, genesisHash, isExternal, isHardware }, buttonText, isFirst, request, signId, url }: Props): React.ReactElement | null { const onAction = useContext(ActionContext); const [{ hexBytes, payload }, setData] = useState({ hexBytes: null, payload: null }); const [error, setError] = useState(null); const { t } = useTranslation(); useEffect((): void => { const payload = request.payload; if (isRawPayload(payload)) { setData({ hexBytes: payload.data, payload: null }); } else { registry.setSignedExtensions(payload.signedExtensions); setData({ hexBytes: null, payload: registry.createType('ExtrinsicPayload', payload, { version: payload.version }) }); } }, [request]); const _onSignature = useCallback( ({ signature }: { signature: HexString }): void => { approveSignSignature(signId, signature) .then(() => onAction()) .catch((error: Error): void => { setError(error.message); console.error(error); }); }, [onAction, signId] ); if (payload !== null) { const json = request.payload as SignerPayloadJSON; return ( <>
{isExternal && !isHardware ? ( ) : ( ) } {isHardware && ( )} ); } else if (hexBytes !== null) { const { address, data } = request.payload as SignerPayloadRaw; return ( <>
{isExternal && !isHardware && genesisHash ? ( ) : ( ) } {isExternal && !isHardware && !genesisHash && ( <> {t('"Allow use on any network" is not supported to show a QR code. You must associate this account with a network.')} )} {isHardware && <> {t('Message signing is not supported for hardware wallets.')} } ); } return null; }