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,108 @@
// Copyright 2017-2025 @pezkuwi/app-staking authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Changes } from '@pezkuwi/react-hooks/useEventChanges';
import type { bool, Option, StorageKey, u32, u128 } from '@pezkuwi/types';
import type { AccountId32, EventRecord } from '@pezkuwi/types/interfaces';
import type { PalletNominationPoolsPoolMember } from '@pezkuwi/types/lookup';
import type { MembersMap, MembersMapEntry } from './types.js';
import { useEffect, useState } from 'react';
import { createNamedHook, useApi, useCall, useEventChanges, useMapEntries } from '@pezkuwi/react-hooks';
const EMPTY_START: AccountId32[] = [];
const OPT_ENTRIES = {
transform: (entries: [StorageKey<[AccountId32]>, Option<PalletNominationPoolsPoolMember>][]): MembersMap =>
entries.reduce((all: MembersMap, [{ args: [accountId] }, optMember]) => {
if (optMember.isSome) {
const member = optMember.unwrap();
const poolId = member.poolId.toString();
if (!all[poolId]) {
all[poolId] = [];
}
all[poolId].push({
accountId: accountId.toString(),
member
});
}
return all;
}, {})
};
const OPT_MULTI = {
transform: ([[ids], values]: [[AccountId32[]], Option<PalletNominationPoolsPoolMember>[]]): MembersMapEntry[] =>
ids
.filter((_, i) => values[i].isSome)
.map((accountId, i) => ({
accountId: accountId.toString(),
member: values[i].unwrap()
})),
withParamsTransform: true
};
function filterEvents (records: EventRecord[]): Changes<AccountId32> {
const added: AccountId32[] = [];
const removed: AccountId32[] = [];
records.forEach(({ event: { data, method } }): void => {
if (method === 'Bonded') {
const [accountId,,, joined] = data as unknown as [AccountId32, u32, u128, bool];
if (joined.isTrue) {
added.push(accountId);
}
}
});
return { added, removed };
}
function interleave (prev: MembersMap, additions: MembersMapEntry[]): MembersMap {
return additions.reduce<MembersMap>((all, entry) => {
const poolId = entry.member.poolId.toString();
const arr: MembersMapEntry[] = [];
if (all[poolId]) {
all[poolId].forEach((prev): void => {
if (prev.accountId !== entry.accountId) {
arr.push(prev);
}
});
}
arr.push(entry);
all[poolId] = arr;
return all;
}, { ...prev });
}
function useMembersImpl (): MembersMap | undefined {
const { api } = useApi();
const [membersMap, setMembersMap] = useState<MembersMap | undefined>();
const queryMap = useMapEntries(api.query.nominationPools.poolMembers, [], OPT_ENTRIES);
const ids = useEventChanges([
api.events.nominationPools.Bonded
], filterEvents, EMPTY_START);
const additions = useCall(ids && ids.length !== 0 && api.query.nominationPools.poolMembers.multi, [ids], OPT_MULTI);
// initial entries
useEffect((): void => {
queryMap && setMembersMap(queryMap);
}, [queryMap]);
// additions via events
useEffect((): void => {
additions && setMembersMap((prev) => prev && interleave(prev, additions));
}, [additions]);
return membersMap;
}
export default createNamedHook('useMembers', useMembersImpl);