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
+184
View File
@@ -0,0 +1,184 @@
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ExtrinsicSignature } from '@pezkuwi/types/interfaces';
import type { Codec, IExtrinsic, IMethod, TypeDef } from '@pezkuwi/types/types';
import type { BN } from '@pezkuwi/util';
import type { ComponentMap } from '../types.js';
import React, { useEffect, useState } from 'react';
import { Static, styled } from '@pezkuwi/react-components';
import Params from '@pezkuwi/react-params';
import { FormatBalance } from '@pezkuwi/react-query';
import { Enum, getTypeDef } from '@pezkuwi/types';
import { balanceCalls, balanceCallsOverrides } from '../overrides.js';
import { useTranslation } from '../translate.js';
export interface Props {
callName?: string;
children?: React.ReactNode;
className?: string;
labelHash?: React.ReactNode;
labelSignature?: React.ReactNode;
mortality?: string;
onError?: () => void;
value?: IExtrinsic | IMethod | null;
withBorder?: boolean;
withExpander?: boolean;
withHash?: boolean;
withSignature?: boolean;
tip?: BN;
}
interface Param {
name: string;
type: TypeDef;
}
interface Value {
isValid: boolean;
value: Codec;
}
interface Extracted {
hash?: string | null;
overrides?: ComponentMap;
params?: Param[];
signature: string | null;
signatureType: string | null;
values?: Value[];
}
function isExtrinsic (value: unknown): value is IExtrinsic {
return !!(value as IExtrinsic).signature;
}
// This is no doubt NOT the way to do things - however there is no other option
function getRawSignature (value: IExtrinsic): ExtrinsicSignature | undefined {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
return (value as any)._raw?.signature?.multiSignature as ExtrinsicSignature;
}
function extractState (value?: IExtrinsic | IMethod | null, withHash?: boolean, withSignature?: boolean, callName?: string): Extracted {
const overrides = callName && balanceCalls.includes(callName)
? balanceCallsOverrides
: undefined;
const params = value?.meta.args.map(({ name, type }): Param => ({
name: name.toString(),
type: getTypeDef(type.toString())
}));
const values = value?.args.map((value): Value => ({
isValid: true,
value
}));
const hash = withHash
? value?.hash.toHex()
: null;
let signature: string | null = null;
let signatureType: string | null = null;
if (withSignature && isExtrinsic(value) && value.isSigned) {
const raw = getRawSignature(value);
signature = value.signature.toHex();
signatureType = raw instanceof Enum
? raw.type
: null;
}
return { hash, overrides, params, signature, signatureType, values };
}
function Call ({ callName, children, className = '', labelHash, labelSignature, mortality, onError, tip, value, withBorder, withExpander, withHash, withSignature }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [{ hash, overrides, params, signature, signatureType, values }, setExtracted] = useState<Extracted>({ hash: null, params: [], signature: null, signatureType: null, values: [] });
useEffect((): void => {
setExtracted(extractState(value, withHash, withSignature, callName));
}, [callName, value, withHash, withSignature]);
return (
<StyledDiv className={`${className} ui--Call`}>
<Params
isDisabled
onError={onError}
overrides={overrides}
params={params}
registry={value?.registry}
values={values}
withBorder={withBorder}
withExpander={withExpander}
>
{children}
<div className='ui--Call--toplevel'>
{hash && (
<Static
className='hash'
label={labelHash || t('extrinsic hash')}
value={hash}
withCopy
/>
)}
{signature && (
<Static
className='hash'
label={labelSignature || t('signature {{type}}', { replace: { type: signatureType ? `(${signatureType})` : '' } })}
value={signature}
withCopy
/>
)}
{mortality && (
<Static
className='mortality'
label={t('lifetime')}
value={mortality}
/>
)}
{tip?.gtn(0) && (
<Static
className='tip'
label={t('tip')}
value={<FormatBalance value={tip} />}
/>
)}
</div>
</Params>
</StyledDiv>
);
}
const StyledDiv = styled.div`
.ui--Labelled.hash .ui--Static {
overflow: hidden;
text-overflow: ellipsis;
word-break: unset;
word-wrap: unset;
white-space: nowrap;
}
.ui--Call--toplevel {
margin-top: 0;
.ui--Labelled {
&:last-child > .ui--Labelled-content > .ui--Static {
margin-bottom: 0;
}
> .ui--Labelled-content > .ui--Static {
background: var(--bg-static-extra);
}
+ .ui--Labelled > .ui--Labelled-content > .ui--Static {
margin-top: 0;
}
}
}
> .ui--Params {
margin-top: -0.25rem;
}
`;
export default React.memo(Call);
@@ -0,0 +1,76 @@
// Copyright 2017-2025 @pezkuwi/react-params authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Call, Extrinsic } from '@pezkuwi/types/interfaces';
import type { BN } from '@pezkuwi/util';
import React, { useMemo } from 'react';
import { Expander } from '@pezkuwi/react-components';
import CallDisplay from './Call.js';
interface Props {
children?: React.ReactNode;
className?: string;
idString?: string;
isHeader?: boolean;
labelHash?: React.ReactNode;
labelSignature?: React.ReactNode;
mortality?: string;
onError?: () => void;
stringId?: string;
tip?: BN;
value?: Call | Extrinsic | null;
withBorder?: boolean;
withHash?: boolean;
withSignature?: boolean;
isExpanded?: boolean
}
function CallExpander ({ children, className = '', isExpanded, isHeader, labelHash, labelSignature, mortality, onError, stringId, tip, value, withBorder, withHash, withSignature }: Props): React.ReactElement<Props> | null {
const call = useMemo(
() => value?.callIndex
? value.registry.findMetaCall(value.callIndex)
: null,
[value]
);
if (!call || !value) {
return null;
}
const { meta, method, section } = call;
const callName = `${section}.${method}`;
return (
<div className={`${className} ui--CallExpander`}>
<Expander
isHeader={isHeader}
isLeft
isOpen={isExpanded}
summaryHead={
<>{stringId && `#${stringId}: `}{callName}</>
}
summaryMeta={meta}
>
<CallDisplay
callName={callName}
labelHash={labelHash}
labelSignature={labelSignature}
mortality={mortality}
onError={onError}
tip={tip}
value={value}
withBorder={withBorder}
withExpander
withHash={withHash}
withSignature={withSignature}
/>
{children}
</Expander>
</div>
);
}
export default React.memo(CallExpander);
+110
View File
@@ -0,0 +1,110 @@
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { DecodedEvent } from '@pezkuwi/api-contract/types';
import type { Event, EventRecord } from '@pezkuwi/types/interfaces';
import type { Codec } from '@pezkuwi/types/types';
import React, { useMemo } from 'react';
import { Input } from '@pezkuwi/react-components';
import { getContractAbi } from '@pezkuwi/react-components/util';
import Params from '@pezkuwi/react-params';
import { balanceEvents, balanceEventsOverrides } from '../overrides.js';
import { useTranslation } from '../translate.js';
export interface Props {
children?: React.ReactNode;
className?: string;
eventName?: string;
value: Event;
withExpander?: boolean;
}
interface Value {
isValid: boolean;
value: Codec;
}
interface AbiEvent extends DecodedEvent {
values: Value[];
}
function EventDisplay ({ children, className = '', eventName, value, withExpander }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const names = value.data.names;
const params = value.typeDef.map((type, i) => ({
name: names?.[i] || undefined,
type
}));
const values = value.data.map((value) => ({ isValid: true, value }));
const overrides = useMemo(
() => eventName && balanceEvents.includes(eventName)
? balanceEventsOverrides
: undefined,
[eventName]
);
const abiEvent = useMemo(
(): AbiEvent | null => {
// for contracts, we decode the actual event
if (value.section === 'contracts' && value.method === 'ContractExecution' && value.data.length === 2) {
// see if we have info for this contract
const [accountId, encoded] = value.data;
try {
const abi = getContractAbi(accountId.toString());
if (abi) {
const decoded = abi.decodeEvent(encoded as EventRecord);
return {
...decoded,
values: decoded.args.map((value) => ({ isValid: true, value }))
};
}
} catch (error) {
// ABI mismatch?
console.error(error);
}
}
return null;
},
[value]
);
return (
<div className={`${className} ui--Event`}>
{children}
<Params
isDisabled
overrides={overrides}
params={params}
registry={value.registry}
values={values}
withExpander={withExpander}
>
{abiEvent && (
<>
<Input
isDisabled
label={t('contract event')}
value={abiEvent.event.identifier}
/>
<Params
isDisabled
params={abiEvent.event.args}
registry={value.registry}
values={abiEvent.values}
/>
</>
)}
</Params>
</div>
);
}
export default React.memo(EventDisplay);
@@ -0,0 +1,151 @@
// Copyright 2017-2025 @pezkuwi/react-params authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { SubmittableExtrinsic, SubmittableExtrinsicFunction } from '@pezkuwi/api/types';
import type { TypeDef } from '@pezkuwi/types/types';
import type { ComponentMap, RawParam } from '../types.js';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { InputExtrinsic } from '@pezkuwi/react-components';
import Params from '@pezkuwi/react-params';
import { getTypeDef } from '@pezkuwi/types/create';
import { isUndefined, objectSpread } from '@pezkuwi/util';
import paramComponents from '../Extra/index.js';
import { balanceCalls, balanceCallsOverrides } from '../overrides.js';
interface Props {
className?: string;
defaultArgs?: RawParam[];
defaultValue: SubmittableExtrinsicFunction<'promise'>;
filter?: (section: string, method?: string) => boolean;
isDisabled?: boolean;
isError?: boolean;
isPrivate?: boolean;
label?: React.ReactNode;
onChange: (method?: SubmittableExtrinsic<'promise'>) => void;
onEnter?: () => void;
onError?: (error?: Error | null) => void;
onEscape?: () => void;
withLabel?: boolean;
}
interface ParamDef {
name: string;
type: TypeDef;
}
interface CallState {
extrinsic: {
fn: SubmittableExtrinsicFunction<'promise'>;
params: ParamDef[];
},
values: RawParam[];
}
const allComponents = objectSpread<ComponentMap>({}, paramComponents, balanceCallsOverrides);
function isValuesValid (params: ParamDef[], values: RawParam[]): boolean {
return values.reduce((isValid, value): boolean =>
isValid &&
!isUndefined(value) &&
!isUndefined(value.value) &&
value.isValid, params.length === values.length
);
}
function getParams ({ meta }: SubmittableExtrinsicFunction<'promise'>): ParamDef[] {
return meta.args.map(({ name, type, typeName }): { name: string; type: TypeDef } => ({
name: name.toString(),
type: {
...getTypeDef(type.toString()),
...(typeName.isSome
? { typeName: typeName.unwrap().toString() }
: {}
)
}
}));
}
function getCallState (fn: SubmittableExtrinsicFunction<'promise'>, values: RawParam[] = []): CallState {
return {
extrinsic: {
fn,
params: getParams(fn)
},
values
};
}
function ExtrinsicDisplay ({ defaultArgs, defaultValue, filter, isDisabled, isError, isPrivate, label, onChange, onEnter, onError, onEscape, withLabel }: Props): React.ReactElement<Props> {
const [{ extrinsic, values }, setDisplay] = useState<CallState>(() => getCallState(defaultValue, defaultArgs));
useEffect((): void => {
const isValid = isValuesValid(extrinsic.params, values);
let method;
if (isValid) {
try {
method = extrinsic.fn(...values.map(({ value }) => value));
} catch (error) {
onError && onError(error as Error);
}
} else {
onError && onError(null);
}
onChange(method);
}, [extrinsic, onChange, onError, values]);
const overrides = useMemo(
() => balanceCalls.includes(`${extrinsic.fn.section}.${extrinsic.fn.method}`)
? allComponents
: paramComponents,
[extrinsic]
);
const _onChangeMethod = useCallback(
(fn: SubmittableExtrinsicFunction<'promise'>) =>
setDisplay((prev): CallState =>
fn.section === prev.extrinsic.fn.section && fn.method === prev.extrinsic.fn.method
? prev
: getCallState(fn)
),
[]
);
const _setValues = useCallback(
(values: RawParam[]) =>
setDisplay(({ extrinsic }) => ({ extrinsic, values })),
[]
);
const { fn: { method, section }, params } = extrinsic;
return (
<div className='extrinsics--Extrinsic'>
<InputExtrinsic
defaultValue={defaultValue}
filter={filter}
isDisabled={isDisabled}
isError={isError}
isPrivate={isPrivate}
label={label}
onChange={_onChangeMethod}
withLabel={withLabel}
/>
<Params
key={`${section}.${method}:params` /* force re-render on change */}
onChange={_setValues}
onEnter={onEnter}
onEscape={onEscape}
overrides={overrides}
params={params}
values={values}
/>
</div>
);
}
export default React.memo(ExtrinsicDisplay);
@@ -0,0 +1,49 @@
// Copyright 2017-2025 @pezkuwi/react-params authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Call } from '@pezkuwi/types/interfaces';
import type { BN } from '@pezkuwi/util';
import React from 'react';
import { formatNumber, isString, isUndefined } from '@pezkuwi/util';
import { useTranslation } from '../translate.js';
import CallExpander from './CallExpander.js';
interface Props {
className?: string;
proposal?: Call | null;
idNumber?: BN | number | string;
withLinks?: boolean;
expandNested?: boolean;
}
function ProposedAction ({ className = '', idNumber, proposal }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const stringId = isString(idNumber) || isUndefined(idNumber)
? idNumber
: formatNumber(idNumber);
if (!proposal) {
return (
<div className={`${className} ui--ProposedAction`}>
<div>{stringId ? `#${stringId}: ` : ''}{t('No execution details available for this proposal')}</div>
</div>
);
}
return (
<div className={`${className} ui--ProposedAction`}>
<CallExpander
isHeader
labelHash={t('preimage')}
stringId={stringId}
value={proposal}
withHash
/>
</div>
);
}
export default React.memo(ProposedAction);
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2017-2025 @pezkuwi/react-params authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { default as Call } from './Call.js';
export { default as CallExpander } from './CallExpander.js';
export { default as Event } from './Event.js';
export { default as Extrinsic } from './Extrinsic.js';
export { default as ProposedAction } from './ProposedAction.js';