mirror of
https://github.com/pezkuwichain/pezkuwi-apps.git
synced 2026-11-14 10:37:05 +00:00
134 lines
3.5 KiB
TypeScript
134 lines
3.5 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/app-utilities authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { HexString } from '@pezkuwi/util/types';
|
|
|
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
|
|
import { createOption } from '@pezkuwi/app-settings/util';
|
|
import { createSs58 } from '@pezkuwi/apps-config';
|
|
import { allNetworks } from '@pezkuwi/networks';
|
|
import { Dropdown, InputAddressSimple, Static } from '@pezkuwi/react-components';
|
|
import { useApi } from '@pezkuwi/react-hooks';
|
|
import { formatNumber, u8aToHex } from '@pezkuwi/util';
|
|
import { base58Decode, checkAddressChecksum, decodeAddress, encodeAddress, isAddress } from '@pezkuwi/util-crypto';
|
|
|
|
import { useTranslation } from './translate.js';
|
|
|
|
interface Props {
|
|
className?: string;
|
|
}
|
|
|
|
interface State {
|
|
inputSS58: number;
|
|
publicKey: HexString | null;
|
|
}
|
|
|
|
function getState (input: string | null): State {
|
|
try {
|
|
if (input && isAddress(input)) {
|
|
const decoded = base58Decode(input);
|
|
const [,,, inputSS58] = checkAddressChecksum(decoded);
|
|
const publicU8a = decodeAddress(input);
|
|
|
|
return {
|
|
inputSS58,
|
|
publicKey: u8aToHex(publicU8a)
|
|
};
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
return {
|
|
inputSS58: 42,
|
|
publicKey: null
|
|
};
|
|
}
|
|
|
|
function Addresses ({ className }: Props): React.ReactElement<Props> {
|
|
const { t } = useTranslation();
|
|
const { chainSS58 } = useApi();
|
|
const [{ inputSS58, publicKey }, setState] = useState<State>({ inputSS58: 42, publicKey: null });
|
|
const [prefix, setPrefix] = useState(-1);
|
|
|
|
const setAddress = useCallback(
|
|
(address: string | null) =>
|
|
setState(getState(address)),
|
|
[]
|
|
);
|
|
|
|
const prefixOptions = useMemo(
|
|
() => {
|
|
const network = allNetworks.find(({ prefix }) => prefix === chainSS58);
|
|
|
|
return createSs58(t).map((o) =>
|
|
createOption(o, ['default'], 'empty', (o.value === -1
|
|
? network
|
|
? ` (${network.displayName}, ${chainSS58 || 0})`
|
|
: ` (${chainSS58 || 0})`
|
|
: ` (${o.value})`
|
|
))
|
|
);
|
|
},
|
|
[chainSS58, t]
|
|
);
|
|
|
|
const converted = useMemo(
|
|
() => publicKey && encodeAddress(publicKey, prefix === -1 ? chainSS58 : prefix),
|
|
[chainSS58, prefix, publicKey]
|
|
);
|
|
|
|
return (
|
|
<div className={className}>
|
|
<div className='ui--row'>
|
|
<InputAddressSimple
|
|
autoFocus
|
|
isError={!publicKey}
|
|
label={t('address to convert')}
|
|
noConvert
|
|
onChange={setAddress}
|
|
/>
|
|
</div>
|
|
<div className='ui--row'>
|
|
<Dropdown
|
|
defaultValue={prefix}
|
|
label={t('address prefix')}
|
|
onChange={setPrefix}
|
|
options={prefixOptions}
|
|
/>
|
|
</div>
|
|
{publicKey && (
|
|
<>
|
|
<div className='ui--row'>
|
|
<Static
|
|
className='medium'
|
|
label={t('input ss58 prefix')}
|
|
value={formatNumber(inputSS58)}
|
|
/>
|
|
</div>
|
|
{converted && (
|
|
<div className='ui--row'>
|
|
<InputAddressSimple
|
|
defaultValue={converted}
|
|
isDisabled
|
|
key={converted}
|
|
label={t('converted address')}
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className='ui--row'>
|
|
<Static
|
|
className='full'
|
|
label={t('hex public key')}
|
|
value={publicKey}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default React.memo(Addresses);
|