mirror of
https://github.com/pezkuwichain/pezkuwi-apps.git
synced 2026-06-13 05:51:03 +00:00
feat: initial Pezkuwi Apps rebrand from polkadot-apps
Rebranded terminology: - Polkadot → Pezkuwi - Kusama → Dicle - Westend → Zagros - Rococo → PezkuwiChain - Substrate → Bizinikiwi - parachain → teyrchain Custom logos with Kurdistan brand colors (#e6007a → #86e62a): - bizinikiwi-hexagon.svg - sora-bizinikiwi.svg - hezscanner.svg - heztreasury.svg - pezkuwiscan.svg - pezkuwistats.svg - pezkuwiassembly.svg - pezkuwiholic.svg
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
// Copyright 2017-2025 @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);
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright 2017-2025 @pezkuwi/app-utilities authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import { Input, Output, Static } from '@pezkuwi/react-components';
|
||||
import { hexToU8a, isHex, stringToU8a } from '@pezkuwi/util';
|
||||
import { blake2AsHex } from '@pezkuwi/util-crypto';
|
||||
|
||||
import { useTranslation } from './translate.js';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
data: string;
|
||||
hash: string;
|
||||
isHexData: boolean;
|
||||
}
|
||||
|
||||
function Hash ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [{ data, hash, isHexData }, setState] = useState<State>({
|
||||
data: '',
|
||||
hash: blake2AsHex(stringToU8a(''), 256),
|
||||
isHexData: false
|
||||
});
|
||||
|
||||
const _onChangeData = useCallback(
|
||||
(data: string): void => {
|
||||
const isHexData = isHex(data);
|
||||
|
||||
setState({
|
||||
data,
|
||||
hash: blake2AsHex(
|
||||
isHexData
|
||||
? hexToU8a(data)
|
||||
: stringToU8a(data),
|
||||
256
|
||||
),
|
||||
isHexData
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className='ui--row'>
|
||||
<Input
|
||||
autoFocus
|
||||
className='full'
|
||||
label={t('from the following data')}
|
||||
onChange={_onChangeData}
|
||||
value={data}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Static
|
||||
className='medium'
|
||||
label={t('hex input data')}
|
||||
value={
|
||||
isHexData
|
||||
? t('Yes')
|
||||
: t('No')
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Output
|
||||
className='full'
|
||||
isHidden={hash.length === 0}
|
||||
isMonospace
|
||||
label={t('the resulting hash is')}
|
||||
value={hash}
|
||||
withCopy
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Hash);
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2017-2025 @pezkuwi/app-utilities authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { RawParamOnChangeValue } from '@pezkuwi/react-params/types';
|
||||
import type { HexString } from '@pezkuwi/util/types';
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import { statics } from '@pezkuwi/react-api';
|
||||
import { Output } from '@pezkuwi/react-components';
|
||||
import { createValue, Holder, ParamComp } from '@pezkuwi/react-params';
|
||||
import { getTypeDef } from '@pezkuwi/types/create';
|
||||
import { u8aToHex } from '@pezkuwi/util';
|
||||
|
||||
function Xcm (): React.ReactElement {
|
||||
const VersionedXcmTypeDef = getTypeDef('XcmVersionedXcm');
|
||||
const [encodedXcm, setEncodedXcm] = useState<HexString>('0x');
|
||||
|
||||
const onChange = useCallback(
|
||||
(_index: number, rawXcm: RawParamOnChangeValue): void => {
|
||||
const xcm = statics.api.createType(VersionedXcmTypeDef.type, rawXcm.value);
|
||||
|
||||
setEncodedXcm(u8aToHex(xcm.toU8a()));
|
||||
},
|
||||
[VersionedXcmTypeDef.type]
|
||||
);
|
||||
|
||||
return (
|
||||
<Holder>
|
||||
<ParamComp
|
||||
defaultValue={ createValue(statics.api.registry, { type: VersionedXcmTypeDef }) }
|
||||
index={0}
|
||||
onChange={onChange}
|
||||
registry={statics.api.registry}
|
||||
type={VersionedXcmTypeDef}
|
||||
/>
|
||||
<Output
|
||||
isDisabled={true}
|
||||
value={encodedXcm}
|
||||
withCopy={true}
|
||||
/>
|
||||
</Holder>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Xcm);
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2017-2025 @pezkuwi/app-utilities authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
import { Route, Routes } from 'react-router';
|
||||
|
||||
import { Tabs } from '@pezkuwi/react-components';
|
||||
|
||||
import Convert from './Convert.js';
|
||||
import Hash from './Hash.js';
|
||||
import { useTranslation } from './translate.js';
|
||||
import Xcm from './Xcm.js';
|
||||
|
||||
interface Props {
|
||||
basePath: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function UtilitiesApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const tabsRef = useRef([
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'convert',
|
||||
text: t('Convert address')
|
||||
},
|
||||
{
|
||||
name: 'hash',
|
||||
text: t('Hash data')
|
||||
},
|
||||
{
|
||||
name: 'xcm',
|
||||
text: t('Encode XCM')
|
||||
}
|
||||
]);
|
||||
|
||||
return (
|
||||
<main className={className}>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={tabsRef.current}
|
||||
/>
|
||||
<Routes>
|
||||
<Route path={basePath}>
|
||||
<Route
|
||||
element={
|
||||
<Xcm />
|
||||
}
|
||||
path='xcm'
|
||||
/>
|
||||
<Route
|
||||
element={
|
||||
<Hash />
|
||||
}
|
||||
path='hash'
|
||||
/>
|
||||
<Route
|
||||
element={
|
||||
<Convert />
|
||||
}
|
||||
index
|
||||
/>
|
||||
</Route>
|
||||
</Routes>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(UtilitiesApp);
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2025 @pezkuwi/app-utilities authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { useTranslation as useTranslationBase } from 'react-i18next';
|
||||
|
||||
interface TOptions {
|
||||
ns?: string;
|
||||
replace?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface Translation {
|
||||
t: (key: string, optionsOrText?: string | TOptions, options?: TOptions) => string
|
||||
}
|
||||
|
||||
export function useTranslation (): Translation {
|
||||
return useTranslationBase('app-utilities') as unknown as Translation;
|
||||
}
|
||||
Reference in New Issue
Block a user