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
@@ -0,0 +1,136 @@
// Copyright 2017-2025 @pezkuwi/app-staking authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ApiPromise } from '@pezkuwi/api';
import type { ContractPromise } from '@pezkuwi/api-contract';
import type { ContractCallOutcome } from '@pezkuwi/api-contract/types';
import type { SignedBlockExtended } from '@pezkuwi/api-derive/types';
import type { ContractLink } from './types.js';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Table } from '@pezkuwi/react-components';
import { useApi, useCall } from '@pezkuwi/react-hooks';
import { formatNumber } from '@pezkuwi/util';
import { useTranslation } from '../translate.js';
import Call from './Call.js';
import Contract from './Contract.js';
import { getContractForAddress } from './util.js';
export interface Props {
contracts: string[];
updated: number;
}
interface Indexes {
contractIndex: number;
messageIndex: number;
onCallResult?: (messageIndex: number, result?: ContractCallOutcome) => void;
}
function filterContracts (api: ApiPromise, keyringContracts: string[] = []): ContractPromise[] {
return keyringContracts
.map((address) => getContractForAddress(api, address.toString()))
.filter((contract): contract is ContractPromise => !!contract);
}
function ContractsTable ({ contracts: keyringContracts }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const newBlock = useCall<SignedBlockExtended>(api.derive.chain.subscribeNewBlocks);
const [{ contractIndex, messageIndex, onCallResult }, setIndexes] = useState<Indexes>({ contractIndex: 0, messageIndex: 0 });
const [isCallOpen, setIsCallOpen] = useState(false);
const [contractLinks, setContractLinks] = useState<Record<string, ContractLink[]>>({});
const headerRef = useRef<[string?, string?, number?][]>([
[t('contracts'), 'start'],
[undefined, undefined, 3],
[t('status'), 'start'],
[]
]);
useEffect((): void => {
if (newBlock) {
const exts = newBlock.block.extrinsics
.filter(({ method }) => api.tx.contracts.call.is(method))
.map(({ args }): ContractLink | null => {
const contractId = keyringContracts.find((a) => args[0].eq(a));
if (!contractId) {
return null;
}
return {
blockHash: newBlock.block.header.hash.toHex(),
blockNumber: formatNumber(newBlock.block.header.number),
contractId
};
})
.filter((value): value is ContractLink => !!value);
exts.length && setContractLinks((links): Record<string, ContractLink[]> => {
exts.forEach((value): void => {
links[value.contractId] = [value].concat(links[value.contractId] || []).slice(0, 3);
});
return { ...links };
});
}
}, [api, keyringContracts, newBlock]);
const contracts = useMemo(
() => filterContracts(api, keyringContracts),
[api, keyringContracts]
);
const _toggleCall = useCallback(
() => setIsCallOpen((isCallOpen) => !isCallOpen),
[]
);
const _onCall = useCallback(
(contractIndex: number, messageIndex: number, onCallResult: (messageIndex: number, result?: ContractCallOutcome) => void): void => {
setIndexes({ contractIndex, messageIndex, onCallResult });
setIsCallOpen(true);
},
[]
);
const _setMessageIndex = useCallback(
(messageIndex: number) => setIndexes((state) => ({ ...state, messageIndex })),
[]
);
const contract = contracts[contractIndex] || null;
return (
<>
<Table
empty={t('No contracts available')}
header={headerRef.current}
>
{contracts.map((contract, index): React.ReactNode => (
<Contract
contract={contract}
index={index}
key={contract.address.toString()}
links={contractLinks[contract.address.toString()]}
onCall={_onCall}
/>
))}
</Table>
{isCallOpen && contract && (
<Call
contract={contract}
messageIndex={messageIndex}
onCallResult={onCallResult}
onChangeMessage={_setMessageIndex}
onClose={_toggleCall}
/>
)}
</>
);
}
export default React.memo(ContractsTable);