Skip to content

Commit

Permalink
fix: request identity through domain (#2836)
Browse files Browse the repository at this point in the history
  • Loading branch information
tuul-wq authored Dec 12, 2024
1 parent ba7355a commit 261ea0f
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 203 deletions.
13 changes: 8 additions & 5 deletions src/renderer/domains/identity/model/identity/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { networkModel } from '@/entities/network';
import { identityService } from './service';
import { type AccountIdentity } from './types';

type Data = Record<AccountId, AccountIdentity>;
type Store = Record<ChainId, Data>;
type IdentityData = Record<AccountId, AccountIdentity>;
type IdentityStore = Record<ChainId, IdentityData>;
type RequestParams = {
accounts: AccountId[];
chainId: ChainId;
Expand All @@ -29,7 +29,7 @@ const {
request: requestIdentity,
pending,
fail,
} = createDataSource<Store, InnerRequestParams, Data>({
} = createDataSource<IdentityStore, InnerRequestParams, IdentityData>({
initial: {},
mutateParams(params, store) {
const chainIdentities = store[params.chainId] ?? {};
Expand All @@ -45,7 +45,7 @@ const {
async fn({ api, accounts }) {
const response = await identityPallet.storage.identityOf(api, accounts);

return response.reduce<Data>((acc, record) => {
return response.reduce<IdentityData>((acc, record) => {
if (record.identity) {
acc[record.account] = {
accountId: record.account,
Expand Down Expand Up @@ -77,7 +77,10 @@ const request = createEvent<RequestParams>();

sample({
clock: request,
source: { apis: $apis, chains: $chains },
source: {
apis: $apis,
chains: $chains,
},
fn: ({ apis, chains }, { chainId, accounts }) => {
const identityChain = identityService.findIdentityChain(chains, chainId);
if (nullable(identityChain)) {
Expand Down
149 changes: 6 additions & 143 deletions src/renderer/entities/staking/api/validatorsService.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { type ApiPromise } from '@polkadot/api';
import { type Data, type Option } from '@polkadot/types';
import { type AccountId32 } from '@polkadot/types/interfaces';
import { type PalletIdentityRegistration } from '@polkadot/types/lookup';
import { u8aToString } from '@polkadot/util';
import merge from 'lodash/merge';

import { type Address, type EraIndex, type Identity, type SubIdentity, type Validator } from '@/shared/core';
import { type Address, type EraIndex, type Validator } from '@/shared/core';
import { DEFAULT_MAX_NOMINATORS, KUSAMA_MAX_NOMINATORS } from '../lib/constants';
import { stakingUtils } from '../lib/staking-utils';
import { type ValidatorMap } from '../lib/types';
Expand Down Expand Up @@ -34,13 +30,9 @@ async function getValidatorsWithInfo(api: ApiPromise, era: EraIndex, isLightClie

const mergedValidators = merge(stake, prefs);

const [identity, slashes] = await Promise.all([
getIdentities(api, Object.keys(mergedValidators), isLightClient),
getSlashingSpans(api, Object.keys(stake), era, isLightClient),
// getApy(api, Object.values(mergedValidators)),
]);
const slashes = await getSlashingSpans(api, Object.keys(stake), era, isLightClient);

return merge(mergedValidators, identity, slashes);
return merge(mergedValidators, slashes);
}

function getValidatorFunction(api: ApiPromise) {
Expand Down Expand Up @@ -78,6 +70,7 @@ async function getValidatorsStake_OLD(api: ApiPromise, era: EraIndex): Promise<V
}

type ValidatorStake = Pick<Validator, 'address' | 'totalStake' | 'oversubscribed' | 'ownStake' | 'nominators'>;

async function getValidatorsStake(api: ApiPromise, era: EraIndex): Promise<Record<Address, ValidatorStake>> {
// HINT: to get full list of nominators uncomment code below to paginate for each validator
const data = await api.query.staking.erasStakersOverview.entries(era);
Expand Down Expand Up @@ -143,132 +136,6 @@ function getMaxValidators(api: ApiPromise): number {
return getDefaultValidatorsAmount(api);
}

// TODO: Temporary turn off identities
async function getIdentities(
api: ApiPromise,
addresses: Address[],
isLightClient?: boolean,
): Promise<Record<Address, { identity: Identity }>> {
return Promise.resolve({});

const subIdentities = await getSubIdentities(api, addresses, isLightClient);
const parentIdentities = await getParentIdentities(api, subIdentities, isLightClient);

return addresses.reduce<Record<Address, { identity: Identity }>>((acc, address) => {
acc[address] = { identity: parentIdentities[address] };

return acc;
}, {});
}

async function getSubIdentities(
api: ApiPromise,
addresses: Address[],
isLightClient?: boolean,
): Promise<SubIdentity[]> {
if (isLightClient) {
const wrappedIdentities = await api.query.identity.superOf.entries();

const subIdentities = wrappedIdentities.reduce<Record<Address, [AccountId32, Data]>>(
(acc, [storageKey, wrappedIdentity]) => {
acc[storageKey.args[0].toString()] = wrappedIdentity.unwrap();

return acc;
},
{},
);

return addresses.reduce<SubIdentity[]>((acc, subAddress) => {
const payload = {
sub: subAddress,
parent: subAddress,
subName: '',
};

if (subIdentities[subAddress]) {
const rawData = subIdentities[subAddress];
payload.parent = rawData[0].toHuman();
payload.subName = rawData[1].isRaw ? u8aToString(rawData[1].asRaw) : rawData[1].value.toString();
}

acc.push(payload);

return acc;
}, []);
}

const subIdentities = await api.query.identity.superOf.multi(addresses);

return subIdentities.reduce<SubIdentity[]>((acc, identity, index) => {
const payload = {
sub: addresses[index],
parent: addresses[index],
subName: '',
};

if (identity.isSome) {
const [address, rawData] = identity.unwrap();
payload.parent = address.toHuman();
payload.subName = rawData.isRaw ? u8aToString(rawData.asRaw) : rawData.value.toString();
}

acc.push(payload);

return acc;
}, []);
}

async function getParentIdentities(
api: ApiPromise,
subIdentities: SubIdentity[],
isLightClient?: boolean,
): Promise<Record<Address, Identity>> {
let parentIdentities;

if (isLightClient) {
const wrappedIdentities = await api.query.identity.identityOf.entries();

const identities = wrappedIdentities.reduce<Record<Address, Option<PalletIdentityRegistration>>>(
(acc, [storageKey, identity]) => {
const address = storageKey.args[0].toString();
// @ts-expect-error TODO fix
acc[address] = identity;

return acc;
},
{},
);

parentIdentities = subIdentities.map((identity) => identities[identity.parent]);
} else {
const identityAddresses = subIdentities.map((identity) => identity.parent);
parentIdentities = await api.query.identity.identityOf.multi(identityAddresses);
}

return parentIdentities.reduce<Record<Address, Identity>>((acc, identity, index) => {
if (!identity || identity.isNone) return acc;

const { parent, sub, subName } = subIdentities[index];
const unwrappedIdentity = identity.unwrap();
// HINT: in runtime 1_4_0 unwrappedIdentity returns Option<(identity, rest)>
const data = 'info' in unwrappedIdentity ? unwrappedIdentity : unwrappedIdentity[0];
const { display, web, email, twitter } = data.info; // { data also includes: judgements, deposit }

acc[sub] = {
subName,
email: email.isRaw ? u8aToString(email.asRaw) : email.value.toString(),
twitter: twitter.isRaw ? u8aToString(twitter.asRaw) : twitter.value.toString(),
website: web.isRaw ? u8aToString(web.asRaw) : web.value.toString(),
parent: {
address: parent,
name: display.isRaw ? u8aToString(display.asRaw) : display.value.toString(),
},
};

return acc;
}, {});
}

// Don't show APY in UI right now
// async function getApy(api: ApiPromise, validators: Validator[]): Promise<Record<Address, { apy: number }>> {
// const apy = await getValidatorsApy(api, validators);
Expand All @@ -278,24 +145,20 @@ async function getParentIdentities(
// }, {});
// }

async function getNominators(api: ApiPromise, stash: Address, isLightClient?: boolean): Promise<ValidatorMap> {
async function getNominators(api: ApiPromise, stash: Address): Promise<ValidatorMap> {
try {
const data = await api.query.staking.nominators(stash);

if (data.isNone) return {};

const nominatorsUnwraped = data.unwrap();

const nominators = nominatorsUnwraped.targets.toArray().reduce<ValidatorMap>((acc, nominator) => {
return nominatorsUnwraped.targets.toArray().reduce<ValidatorMap>((acc, nominator) => {
const address = nominator.toString();
acc[address] = { address } as Validator;

return acc;
}, {});

const identities = await getIdentities(api, Object.keys(nominators), isLightClient);

return merge(nominators, identities);
} catch (error) {
console.warn(error);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { type Validator } from '@/shared/core/types/validator';
import { useI18n } from '@/shared/i18n';
import { toAccountId } from '@/shared/lib/utils';
import { type AccountId } from '@/shared/polkadotjs-schemas';
import { BaseModal } from '@/shared/ui';
// eslint-disable-next-line boundaries/element-types
import { type AccountIdentity } from '@/domains/identity';
import { ValidatorsTable } from '../ValidatorsTable/ValidatorsTable';

type Props = {
isOpen: boolean;
validators: Validator[];
identities: Record<AccountId, AccountIdentity>;
onClose: () => void;
};

export const SelectedValidatorsModal = ({ isOpen, validators, onClose }: Props) => {
export const SelectedValidatorsModal = ({ isOpen, validators, identities, onClose }: Props) => {
const { t } = useI18n();

return (
Expand All @@ -28,7 +33,10 @@ export const SelectedValidatorsModal = ({ isOpen, validators, onClose }: Props)
key={validator.address}
className="group grid h-10 shrink-0 grid-cols-[1fr,40px] items-center pl-5 pr-2 hover:bg-hover"
>
<ValidatorsTable.ShortRow validator={validator} />
<ValidatorsTable.ShortRow
validator={validator}
identity={identities[toAccountId(validator.address) as AccountId]}
/>
</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,11 @@ describe('pages/Staking/components/ValidatorsModal', () => {
isOpen: true,
amount: '1000000000000',
asset: { symbol: 'DOT', precision: 10 } as Asset,
identities: {},
selectedValidators: [
{
address: '12QkLhnKL5vXsa7e74CC45RUSqA5fRqc8rKHzXYZb82ppZap',
identity: {
subName: 'subName',
parent: { name: 'parent', address: '0x123' },
},
},
{
address: 'EGSgCCMmg5vePv611bmJpgdy7CaXaHayqPH8XwgD1jetWjN',
identity: {
subName: 'subName',
parent: { name: 'parent', address: '0x123' },
},
},
{
address: '5H46Nxu6sJvTYe4rSUxYTUU6pG5dh6jZq66je2g7SLE3RCj6',
identity: {
subName: 'subName',
parent: { name: 'parent', address: '0x123' },
},
},
{ address: '12QkLhnKL5vXsa7e74CC45RUSqA5fRqc8rKHzXYZb82ppZap' },
{ address: 'EGSgCCMmg5vePv611bmJpgdy7CaXaHayqPH8XwgD1jetWjN' },
{ address: '5H46Nxu6sJvTYe4rSUxYTUU6pG5dh6jZq66je2g7SLE3RCj6' },
] as Validator[],
notSelectedValidators: [],
onClose: () => {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { type Asset, type Explorer } from '@/shared/core';
import { type Validator } from '@/shared/core/types/validator';
import { useI18n } from '@/shared/i18n';
import { cnTw } from '@/shared/lib/utils';
import { cnTw, toAccountId } from '@/shared/lib/utils';
import { type AccountId } from '@/shared/polkadotjs-schemas';
import { Accordion, BaseModal, SmallTitleText } from '@/shared/ui';
// eslint-disable-next-line boundaries/element-types
import { type AccountIdentity } from '@/domains/identity';
import { ValidatorsTable } from '../ValidatorsTable/ValidatorsTable';

type Props = {
isOpen: boolean;
selectedValidators: Validator[];
notSelectedValidators: Validator[];
identities: Record<AccountId, AccountIdentity>;
asset?: Asset;
explorers?: Explorer[];
onClose: () => void;
Expand All @@ -18,6 +22,7 @@ export const ValidatorsModal = ({
isOpen,
selectedValidators,
notSelectedValidators,
identities,
explorers,
asset,
onClose,
Expand Down Expand Up @@ -45,7 +50,12 @@ export const ValidatorsModal = ({
<ValidatorsTable validators={selectedValidators} listClassName="max-h-none">
{(validator, rowStyle) => (
<li key={validator.address} className={cnTw(rowStyle, 'group hover:bg-hover')}>
<ValidatorsTable.Row validator={validator} asset={asset} explorers={explorers} />
<ValidatorsTable.Row
validator={validator}
identity={identities[toAccountId(validator.address) as AccountId]}
asset={asset}
explorers={explorers}
/>
</li>
)}
</ValidatorsTable>
Expand All @@ -63,7 +73,12 @@ export const ValidatorsModal = ({
<ValidatorsTable validators={notSelectedValidators} listClassName="max-h-none">
{(validator, rowStyle) => (
<li key={validator.address} className={cnTw(rowStyle, 'group hover:bg-hover')}>
<ValidatorsTable.Row validator={validator} asset={asset} explorers={explorers} />
<ValidatorsTable.Row
validator={validator}
identity={identities[toAccountId(validator.address) as AccountId]}
asset={asset}
explorers={explorers}
/>
</li>
)}
</ValidatorsTable>
Expand Down
Loading

0 comments on commit 261ea0f

Please sign in to comment.