Skip to content

Commit

Permalink
fix: correct account for voting in fellowship (#2948)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnthecat authored Jan 10, 2025
1 parent b9f8c46 commit c76a1bf
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 41 deletions.
13 changes: 11 additions & 2 deletions src/renderer/domains/collectives/members/service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { dictionary } from '@/shared/lib/utils';
import { type AnyAccount } from '@/domains/network';
import { type AnyAccount, accountsService } from '@/domains/network';

import { type CoreMember, type Member } from './types';

Expand All @@ -10,7 +10,16 @@ const findMatchingMember = (accounts: AnyAccount[], members: Member[]) => {
};

const findMatchingAccount = (accounts: AnyAccount[], member: Member) => {
return accounts.find(a => a.accountId === member.accountId) ?? null;
const found = accounts.filter(a => a.accountId === member.accountId);

if (found.length > 1) {
const accountWithWritePermission = found.find(accountsService.hasPermissionToMakeActions);
if (accountWithWritePermission) {
return accountWithWritePermission;
}
}

return found.at(0) ?? null;
};

const isCoreMember = (member: Member | CoreMember): member is CoreMember => {
Expand Down
69 changes: 39 additions & 30 deletions src/renderer/features/fellowship-voting/components/VotingModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const VotingModal = ({ isOpen, onClose, vote }: Props) => {
}

const wallet = walletUtils.getWalletFilteredAccounts(input.wallets, {
walletFn: w => w.id === account.walletId,
accountFn: a => a.accountId === account.accountId,
});

Expand Down Expand Up @@ -77,42 +78,50 @@ export const VotingModal = ({ isOpen, onClose, vote }: Props) => {
);
}

if (nullable(account)) {
return (
<OperationResult
isOpen={isOpen}
variant="error"
autoCloseTimeout={2000}
title={t('fellowship.voting.errors.noAccount')}
onClose={onClose}
/>
);
}

return (
<Modal isOpen={isOpen} size="md" onToggle={handleToggle}>
<Modal.Title close>
<OperationTitle title={t('fellowship.voting.title')} chainId={input.chainId} />
</Modal.Title>
<Modal.Content>
{nonNullable(account) ? (
<Carousel item={step}>
<Carousel.Item id="confirm" index={0}>
<Box>
<Box padding={[4, 5]}>
<VotingConfirmation
asset={input.asset}
chain={input.chain}
wallets={input.wallets}
account={account}
vote={vote}
rank={member.rank}
fee={fee}
/>
</Box>
<Modal.Footer>
{wallet && basketUtils.isBasketAvailable(wallet) && (
<Button pallet="secondary" onClick={handleBasketSave}>
{t('operation.addToBasket')}
</Button>
)}
{nonNullable(wallet) && <SignButton type={wallet.type} onClick={handleSign} />}
</Modal.Footer>
</Box>
</Carousel.Item>
<Carousel.Item id="sign" index={1}>
<OperationSign onGoBack={() => setStep('confirm')} />
</Carousel.Item>
</Carousel>
) : null}
<Carousel item={step}>
<Carousel.Item id="confirm" index={0}>
<Box padding={[4, 5]}>
<VotingConfirmation
asset={input.asset}
chain={input.chain}
wallets={input.wallets}
account={account}
vote={vote}
rank={member.rank}
fee={fee}
/>
</Box>
<Modal.Footer>
{wallet && basketUtils.isBasketAvailable(wallet) && (
<Button pallet="secondary" onClick={handleBasketSave}>
{t('operation.addToBasket')}
</Button>
)}
{nonNullable(wallet) && <SignButton type={wallet.type} onClick={handleSign} />}
</Modal.Footer>
</Carousel.Item>
<Carousel.Item id="sign" index={1}>
<OperationSign onGoBack={() => setStep('confirm')} />
</Carousel.Item>
</Carousel>
</Modal.Content>
</Modal>
);
Expand Down
1 change: 0 additions & 1 deletion src/renderer/features/fellowship-voting/model/basket.ts

This file was deleted.

5 changes: 4 additions & 1 deletion src/renderer/features/fellowship-voting/model/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { combine } from 'effector';

import { createFeature } from '@/shared/feature';
import { nullable } from '@/shared/lib/utils';
import { accounts } from '@/domains/network';
import { walletModel } from '@/entities/wallet';
import { fellowshipNetworkFeature } from '@/features/fellowship-network';

Expand All @@ -10,8 +11,9 @@ const $input = combine(
network: fellowshipNetworkFeature.model.network.$network,
wallets: walletModel.$wallets,
wallet: walletModel.$activeWallet,
accounts: accounts.$list,
},
({ network, wallets, wallet }) => {
({ network, wallets, wallet, accounts }) => {
if (nullable(network) || nullable(wallet)) return null;

return {
Expand All @@ -21,6 +23,7 @@ const $input = combine(
chainId: network.chainId,
palletType: network.palletType,
activeAccounts: wallet.accounts,
accounts,
wallets,
wallet,
};
Expand Down
14 changes: 7 additions & 7 deletions src/renderer/features/fellowship-voting/model/votingStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { createGate } from 'effector-react';
import { attachToFeatureInput } from '@/shared/feature';
import { nonNullable, nullable, toKeysRecord } from '@/shared/lib/utils';
import { type ReferendumId } from '@/shared/pallet/referenda';
import { pjsSchema } from '@/shared/polkadotjs-schemas';
import { collectiveDomain } from '@/domains/collectives';
import { accountsService } from '@/domains/network';

import { fellowshipModel } from './fellowship';
import { votingFeatureStatus } from './status';
Expand All @@ -24,16 +24,16 @@ const $referendum = combine($referendums, $referendumId, (referendums, referendu
return referendums.find(referendum => referendum.id === referendumId) ?? null;
});

const $currentMember = combine(votingFeatureStatus.input, $members, (featureInput, members) => {
if (nullable(featureInput)) return null;
const $currentMember = combine(votingFeatureStatus.input, $members, (input, members) => {
if (nullable(input)) return null;

return collectiveDomain.membersService.findMatchingMember(featureInput.activeAccounts, members);
return collectiveDomain.membersService.findMatchingMember(input.accounts, members);
});

const $votingAccount = combine(votingFeatureStatus.input, $currentMember, (input, member) => {
if (nullable(member) || nullable(input)) return null;

return collectiveDomain.membersService.findMatchingAccount(input.activeAccounts, member);
return collectiveDomain.membersService.findMatchingAccount(input.accounts, member);
});

const $hasRequiredRank = combine(
Expand All @@ -51,7 +51,7 @@ const $hasRequiredRank = combine(
},
);

const $canVote = $currentMember.map(nonNullable);
const $canVote = $votingAccount.map(a => nonNullable(a) && accountsService.hasPermissionToMakeActions(a));

const $walletVoting = restore(
attachToFeatureInput(votingFeatureStatus, $voting).map(({ input: { wallet }, data: voting }) => {
Expand All @@ -75,7 +75,7 @@ sample({
api,
chainId,
referendums: referendums.map(r => r.id),
accounts: activeAccounts.map(a => pjsSchema.helpers.toAccountId(a.accountId)),
accounts: activeAccounts.map(a => a.accountId),
};
},

Expand Down
7 changes: 7 additions & 0 deletions src/renderer/features/wallet-multisig/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { $features } from '@/shared/config/features';
import { WalletType } from '@/shared/core';
import { createFeature } from '@/shared/feature';
import { useI18n } from '@/shared/i18n';
import { accountsService } from '@/domains/network';
import { accountUtils } from '@/entities/wallet';
import { walletGroupSlot } from '@/features/wallet-select';

import { WalletGroup, walletActionsSlot } from './components/WalletGroup';
Expand All @@ -16,6 +18,11 @@ export const walletMultisigFeature = createFeature({
enable: $features.map(f => f.multisig || f.flexibleMultisig),
});

// All multisig accounts can perform actions
walletMultisigFeature.inject(accountsService.accountActionPermissionAnyOf, ({ account }) => {
return accountUtils.isMultisigAccount(account);
});

walletMultisigFeature.inject(walletGroupSlot, {
order: 1,
render({ query, onSelect }) {
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/features/wallet-polkadot-vault/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { $features } from '@/shared/config/features';
import { WalletType } from '@/shared/core';
import { createFeature } from '@/shared/feature';
import { useI18n } from '@/shared/i18n';
import { accountsService } from '@/domains/network';
import { accountUtils } from '@/entities/wallet';
import { walletGroupSlot } from '@/features/wallet-select';

import { WalletGroup, walletActionsSlot } from './components/WalletGroup';
Expand All @@ -16,6 +18,14 @@ export const walletPolkadotVaultFeature = createFeature({
enable: $features.map(f => f.polkadotVault),
});

walletPolkadotVaultFeature.inject(accountsService.accountActionPermissionAnyOf, ({ account }) => {
return (
accountUtils.isVaultBaseAccount(account) ||
accountUtils.isVaultChainAccount(account) ||
accountUtils.isVaultShardAccount(account)
);
});

walletPolkadotVaultFeature.inject(walletGroupSlot, {
order: 0,
render({ query, onSelect }) {
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/features/wallet-proxied/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { $features } from '@/shared/config/features';
import { WalletType } from '@/shared/core';
import { createFeature } from '@/shared/feature';
import { useI18n } from '@/shared/i18n';
import { accountsService } from '@/domains/network';
import { accountUtils } from '@/entities/wallet';
import { walletGroupSlot } from '@/features/wallet-select';

import { WalletGroup, walletActionsSlot } from './components/WalletGroup';
Expand All @@ -16,6 +18,10 @@ export const walletProxiedFeature = createFeature({
enable: $features.map(f => f.proxy),
});

walletProxiedFeature.inject(accountsService.accountActionPermissionAnyOf, ({ account }) => {
return accountUtils.isProxiedAccount(account);
});

walletProxiedFeature.inject(walletGroupSlot, {
order: 3,
render({ query, onSelect }) {
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/features/wallet-wallet-connect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { $features } from '@/shared/config/features';
import { WalletType } from '@/shared/core';
import { createFeature } from '@/shared/feature';
import { useI18n } from '@/shared/i18n';
import { accountsService } from '@/domains/network';
import { accountUtils } from '@/entities/wallet';
import { walletGroupSlot } from '@/features/wallet-select';

import { WalletGroup, walletActionsSlot } from './components/WalletGroup';
Expand All @@ -16,6 +18,10 @@ export const walletWalletConnectFeature = createFeature({
enable: $features.map(f => f.walletConnect),
});

walletWalletConnectFeature.inject(accountsService.accountActionPermissionAnyOf, ({ account }) => {
return accountUtils.isWcAccount(account);
});

walletWalletConnectFeature.inject(walletGroupSlot, {
order: 2,
render({ query, onSelect }) {
Expand Down
1 change: 1 addition & 0 deletions src/renderer/shared/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@
"voting": {
"voted": "Voted:",
"errors": {
"noAccount": "Account for voting not found",
"rankThreshold": "You cannot vote in this referendum because your rank is below the required level."
},
"votingStatus": "Voting status",
Expand Down

0 comments on commit c76a1bf

Please sign in to comment.