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:
2026-01-07 13:05:27 +03:00
commit d21bfb1320
5867 changed files with 329019 additions and 0 deletions
+133
View File
@@ -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);
+84
View File
@@ -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);
+46
View File
@@ -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);
+70
View File
@@ -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);
+17
View File
@@ -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;
}