Skip to content

Commit

Permalink
Merge branch 'dev' into feat/history
Browse files Browse the repository at this point in the history
  • Loading branch information
tuul-wq authored Feb 21, 2025
2 parents 56af85b + 8fd0713 commit 7b0fad4
Show file tree
Hide file tree
Showing 56 changed files with 694 additions and 330 deletions.
4 changes: 2 additions & 2 deletions src/renderer/aggregates/fellowship-member/model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { combine } from 'effector';

import { member, memberService } from '@/domains/collectives';
import { accountsService } from '@/domains/network';
import { accountService } from '@/domains/network';
import { walletModel } from '@/entities/wallet';
import { fellowshipNetwork } from '@/aggregates/fellowship-network';
import { walletSelect } from '@/aggregates/wallet-select';
Expand All @@ -12,7 +12,7 @@ const $chainMembers = combine(fellowshipNetwork.$network, $fellowshipMembers, (n
);

const $accounts = combine(fellowshipNetwork.$network, walletModel.$availableAccounts, (network, accounts) =>
network ? accountsService.filterAccountOnChain(accounts, network.chain) : [],
network ? accountService.filterAccountOnChain(accounts, network.chain) : [],
);

const $currentMember = combine(
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/aggregates/wallet-select/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { attach, combine, sample } from 'effector';

import { type ID } from '@/shared/core';
import { nullable } from '@/shared/lib/utils';
import { accounts, accountsService } from '@/domains/network';
import { accountService, accounts } from '@/domains/network';
import { walletModel } from '@/entities/wallet';

const $selectedWallet = walletModel.$wallets.map(wallets => {
Expand All @@ -14,7 +14,7 @@ const $selectedWalletId = $selectedWallet.map(w => w?.id ?? null);
const $selectedAccounts = combine($selectedWallet, accounts.$list, (wallet, accounts) => {
if (nullable(wallet)) return [];

return accountsService.filterAccountsByWallet(accounts, wallet.id);
return accountService.filterAccountsByWallet(accounts, wallet.id);
});

const selectWalletFx = attach({
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/domains/collectives/members/service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type Chain, type Transaction, TransactionType } from '@/shared/core';
import { dictionary, toAddress } from '@/shared/lib/utils';
import { type AnyAccount, accountsService } from '@/domains/network';
import { type AnyAccount, accountService } from '@/domains/network';
import { type CollectivePalletsType } from '../_lib/types';

import { type CoreMember, type Member, type SetActiveTransaction } from './types';
Expand All @@ -24,7 +24,7 @@ function findMatchingAccount(accounts: AnyAccount[], member: Member, selectedWal

if (found.length > 1) {
const currentWalletAccounts = found.filter(a => a.walletId === selectedWallet);
const accountWithWritePermission = currentWalletAccounts.find(accountsService.hasPermissionToMakeActions);
const accountWithWritePermission = currentWalletAccounts.find(accountService.hasPermissionToMakeActions);
if (accountWithWritePermission) {
return accountWithWritePermission;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { once, readonly } from 'patronum';
import { storageService } from '@/shared/api/storage';
import { merge, nonNullable } from '@/shared/lib/utils';

import { accountsService } from './service';
import { accountService } from './service';
import { type AnyAccount, type AnyAccountDraft } from './types';

const $accounts = createStore<AnyAccount[]>([]);
Expand All @@ -18,15 +18,15 @@ const populateFx = createEffect((): Promise<AnyAccount[]> => storageService.acco

const createAccountsFx = createEffect(async (accounts: AnyAccountDraft[]): Promise<AnyAccount[]> => {
return storageService.accounts2
.createAll(accounts.map(a => ({ ...a, id: accountsService.uniqId(a) })))
.createAll(accounts.map(a => ({ ...a, id: accountService.uniqId(a) })))
.then(x => x ?? []);
});

const updateAccountsFx = createEffect(async (accounts: AnyAccountDraft[]): Promise<boolean> => {
if (accounts.length === 0) return false;

const drafts = accounts.map(a => {
const id = accountsService.uniqId(a);
const id = accountService.uniqId(a);

return { ...a, id };
});
Expand All @@ -37,7 +37,7 @@ const updateAccountsFx = createEffect(async (accounts: AnyAccountDraft[]): Promi
const updateAccount = attach({
source: $accounts,
mapParams: (draft: AnyAccountDraft, accounts) => {
if (accounts.find(a => accountsService.uniqId(a) === accountsService.uniqId(draft))) {
if (accounts.find(a => accountService.uniqId(a) === accountService.uniqId(draft))) {
return [draft];
}

Expand All @@ -48,7 +48,7 @@ const updateAccount = attach({

const deleteAccountsFx = createEffect(async (accounts: AnyAccount[]) => {
// TODO set correct id
await storageService.accounts2.deleteAll(accounts.map(accountsService.uniqId));
await storageService.accounts2.deleteAll(accounts.map(accountService.uniqId));

return accounts;
});
Expand All @@ -65,7 +65,7 @@ sample({
merge({
a: accounts,
b: newAccounts,
mergeBy: accountsService.uniqId,
mergeBy: accountService.uniqId,
}),
target: $accounts,
});
Expand All @@ -75,9 +75,9 @@ sample({
source: $accounts,
filter: (_, { result: successful }) => successful,
fn: (accounts, { params: draft }) => {
const draftId = accountsService.uniqId(draft);
const draftId = accountService.uniqId(draft);

return accounts.map(a => (accountsService.uniqId(a) === draftId ? { ...a, ...draft } : a));
return accounts.map(a => (accountService.uniqId(a) === draftId ? { ...a, ...draft } : a));
},
target: $accounts,
});
Expand All @@ -88,13 +88,13 @@ sample({
filter: (_, { result: successful }) => successful,
fn: (accounts, { params: drafts }) => {
const draftsMap = drafts.reduce<Record<string, AnyAccountDraft>>((acc, draft) => {
acc[accountsService.uniqId(draft)] = draft;
acc[accountService.uniqId(draft)] = draft;

return acc;
}, {});

return accounts.map<AnyAccount>(a =>
accountsService.uniqId(a) in draftsMap ? { ...a, ...draftsMap[accountsService.uniqId(a)] } : a,
accountService.uniqId(a) in draftsMap ? { ...a, ...draftsMap[accountService.uniqId(a)] } : a,
);
},
target: $accounts,
Expand All @@ -104,9 +104,9 @@ sample({
clock: deleteAccountsFx.done,
source: $accounts,
fn: (accounts, { result: deletedAccounts }) => {
const deletedIds = deletedAccounts.map(accountsService.uniqId);
const deletedIds = deletedAccounts.map(accountService.uniqId);

return accounts.filter(a => !deletedIds.includes(accountsService.uniqId(a)));
return accounts.filter(a => !deletedIds.includes(accountService.uniqId(a)));
},
target: $accounts,
});
Expand Down
173 changes: 173 additions & 0 deletions src/renderer/domains/network/account/service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import { CryptoType, SigningType } from '@/shared/core';
import { createAccountId, kusamaChainId, polkadotChain, polkadotChainId } from '@/shared/mocks';
import { type AccountId } from '@/shared/polkadotjs-schemas';

import { accountService } from './service';
import { type AnyAccount, type ChainAccount, type UniversalAccount } from './types';

const chainAccount: ChainAccount = {
id: 'chain',
type: 'chain',
accountId: createAccountId('1'),
chainId: polkadotChainId,
name: '',
walletId: 0,
signingType: SigningType.POLKADOT_VAULT,
cryptoType: CryptoType.SR25519,
};

const kusamaChainAccount: ChainAccount = {
id: 'kusama',
type: 'chain',
accountId: createAccountId('2'),
chainId: kusamaChainId,
name: '',
walletId: 0,
signingType: SigningType.POLKADOT_VAULT,
cryptoType: CryptoType.SR25519,
};

const universalAccount: UniversalAccount = {
id: 'universal',
type: 'universal',
accountId: createAccountId('3'),
name: '',
walletId: 0,
signingType: SigningType.POLKADOT_VAULT,
cryptoType: CryptoType.SR25519,
};

describe('accounts service', () => {
it('should check account types', async () => {
expect(accountService.isChainAccount(chainAccount)).toEqual(true);
expect(accountService.isChainAccount(universalAccount)).toEqual(false);
expect(accountService.isUniversalAccount(universalAccount)).toEqual(true);
expect(accountService.isUniversalAccount(chainAccount)).toEqual(false);
});

it('should filter accounts by chainId', async () => {
const filtered = accountService.filterAccountOnChain(
[chainAccount, kusamaChainAccount, universalAccount],
polkadotChain,
);

expect(filtered).toEqual([chainAccount]);
});

it('should filter accounts by chainId', async () => {
const spy = jest.fn().mockReturnValue(true);
accountService.accountAvailabilityOnChainAnyOf.registerHandler({ body: spy, available: () => true });

const filtered = accountService.filterAccountOnChain(
[kusamaChainAccount, chainAccount, universalAccount],
polkadotChain,
);

expect(filtered).toEqual([chainAccount, universalAccount]);
expect(spy).toBeCalledWith({ account: universalAccount, chain: polkadotChain });

accountService.accountAvailabilityOnChainAnyOf.resetHandlers();
});

it('should create graphs', async () => {
interface NestedAccount extends ChainAccount {
child: AccountId;
}

const isNested = (a: AnyAccount): a is NestedAccount => {
return 'child' in a;
};

const firstNestedAccount: NestedAccount = {
id: '',
type: 'chain',
name: 'test',
walletId: 0,
chainId: polkadotChainId,
accountId: createAccountId('1'),
cryptoType: CryptoType.SR25519,
signingType: SigningType.WALLET_CONNECT,
child: createAccountId('2'),
};

const secondNestedAccount: NestedAccount = {
id: '',
type: 'chain',
name: 'test',
walletId: 1,
chainId: polkadotChainId,
accountId: createAccountId('2'),
cryptoType: CryptoType.SR25519,
signingType: SigningType.WALLET_CONNECT,
child: createAccountId('3'),
};

const leafAccount: ChainAccount = {
id: '',
type: 'chain',
name: 'test',
walletId: 2,
chainId: polkadotChainId,
accountId: createAccountId('3'),
cryptoType: CryptoType.SR25519,
signingType: SigningType.POLKADOT_VAULT,
};

const accounts = [leafAccount, secondNestedAccount, firstNestedAccount];

accountService.accountActionPermissionAnyOf.registerHandler({
body: () => true,
available: () => true,
});
accountService.accountGraphCollectPipeline.registerHandler({
body(node, { accounts }) {
const account = node.account;
if (isNested(account)) {
const child = accounts.find(a => a.accountId === account.child);

if (!child) {
return node;
}

return {
account,
children: [
accountService.accountGraphCollectPipeline(
{
account: child,
children: [],
},
{ accounts },
),
],
};
}

return node;
},
available: () => true,
});

const graphs = accountService.createAccountGraphs(accounts, polkadotChain);

const firstNestedNode = graphs.get(firstNestedAccount);
const secondNestedNode = graphs.get(secondNestedAccount);
const childNode = graphs.get(leafAccount);

assert(firstNestedNode, 'graph should include nested account');
assert(secondNestedNode, 'graph should include nested account');
assert(childNode, 'graph should include child account');

expect(firstNestedNode.children.length).toBe(1);
expect(secondNestedNode.children.length).toBe(1);
expect(childNode.children.length).toBe(0);

expect(accountService.findRoute(firstNestedAccount, leafAccount, accounts, polkadotChain)).toEqual([
firstNestedAccount,
secondNestedAccount,
leafAccount,
]);
expect(accountService.findSignatories(firstNestedAccount, accounts, polkadotChain)).toEqual([leafAccount]);
expect(accountService.findInitiators(accounts, polkadotChain)).toEqual([firstNestedAccount]);
});
});
Loading

0 comments on commit 7b0fad4

Please sign in to comment.