From 5d77609ebfa0c7150631f4b301529212270e25d0 Mon Sep 17 00:00:00 2001 From: Sergey Zhuravlev Date: Tue, 19 Nov 2024 11:31:07 +0300 Subject: [PATCH] fix: multisig wallet select should work fine now (#2677) --- .../entities/wallet/model/wallet-model.ts | 13 ++- .../features/proxies/model/proxies-model.ts | 1 + .../WalletSelect/model/wallet-select-model.ts | 4 +- .../ManageMultishard/ManageMultishard.tsx | 1 + .../ManageSingleshard/ManageSingleshard.tsx | 1 + .../ManageVault/model/manage-vault-model.ts | 1 + .../Onboarding/WalletConnect/ManageStep.tsx | 1 + .../pages/Onboarding/WatchOnly/WatchOnly.tsx | 1 + .../model/__tests__/multisigs-model.test.ts | 82 +------------------ .../multisigs/model/multisigs-model.ts | 6 +- .../widgets/CreateWallet/model/flow-model.ts | 3 +- 11 files changed, 25 insertions(+), 89 deletions(-) diff --git a/src/renderer/entities/wallet/model/wallet-model.ts b/src/renderer/entities/wallet/model/wallet-model.ts index 191ba8ff94..d7c0840763 100644 --- a/src/renderer/entities/wallet/model/wallet-model.ts +++ b/src/renderer/entities/wallet/model/wallet-model.ts @@ -1,4 +1,4 @@ -import { combine, createEffect, createEvent, createStore, sample } from 'effector'; +import { type UnitValue, combine, createEffect, createEvent, createStore, sample } from 'effector'; import groupBy from 'lodash/groupBy'; import { combineEvents, readonly } from 'patronum'; @@ -23,6 +23,9 @@ type DbWallet = Omit; type CreateParams = { wallet: Omit, 'isActive' | 'accounts'>; accounts: Omit, 'walletId'>[]; + // external means wallet was created by someone else and discovered later + // TODO this flag is related to multisig creation and should disappear after wallet feature decomposition + external: boolean; }; const walletStarted = createEvent(); @@ -85,6 +88,7 @@ const fetchAllWalletsFx = createEffect(async (): Promise => { type CreateResult = { wallet: DbWallet; accounts: Account[]; + external: boolean; }; const walletCreatedFx = createEffect(async ({ wallet, accounts }: CreateParams): Promise => { const dbWallet = await storageService.wallets.create({ ...wallet, isActive: false }); @@ -96,14 +100,15 @@ const walletCreatedFx = createEffect(async ({ wallet, accounts }: CreateParams): if (!dbAccounts) return undefined; - return { wallet: dbWallet, accounts: dbAccounts }; + return { wallet: dbWallet, accounts: dbAccounts, external: false }; }); const multishardCreatedFx = createEffect( async ({ wallet, accounts, - }: CreateParams): Promise => { + external, + }: UnitValue): Promise<(CreateResult & { external: boolean }) | undefined> => { const dbWallet = await storageService.wallets.create({ ...wallet, isActive: false }); if (!dbWallet) return undefined; @@ -148,7 +153,7 @@ const multishardCreatedFx = createEffect( multishardAccounts.push(...dbChainAccounts); } - return { wallet: dbWallet, accounts: multishardAccounts }; + return { wallet: dbWallet, accounts: multishardAccounts, external }; }, ); diff --git a/src/renderer/features/proxies/model/proxies-model.ts b/src/renderer/features/proxies/model/proxies-model.ts index 8a352431d9..2fe74cbe15 100644 --- a/src/renderer/features/proxies/model/proxies-model.ts +++ b/src/renderer/features/proxies/model/proxies-model.ts @@ -322,6 +322,7 @@ sample({ return { wallet, accounts: account ? [account] : [], + external: false, }; }); diff --git a/src/renderer/features/wallets/WalletSelect/model/wallet-select-model.ts b/src/renderer/features/wallets/WalletSelect/model/wallet-select-model.ts index 613ae46c69..5a7878d5ee 100644 --- a/src/renderer/features/wallets/WalletSelect/model/wallet-select-model.ts +++ b/src/renderer/features/wallets/WalletSelect/model/wallet-select-model.ts @@ -119,11 +119,11 @@ sample({ sample({ clock: walletModel.events.walletCreatedDone, source: walletModel.$wallets, - filter: (wallets, { wallet }) => { + filter: (wallets, { wallet, external }) => { const foundWallet = wallets.find((w) => w.id === wallet.id); if (!foundWallet) return false; - return !walletUtils.isProxied(foundWallet) && !walletUtils.isMultisig(foundWallet); + return !walletUtils.isProxied(foundWallet) && !walletUtils.isMultisig(foundWallet) && !external; }, fn: (_, { wallet }) => wallet.id, target: walletModel.events.selectWallet, diff --git a/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx b/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx index 5758331073..a2ad3bf282 100644 --- a/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx +++ b/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx @@ -186,6 +186,7 @@ export const ManageMultishard = ({ seedInfo, onBack, onClose, onComplete }: Prop signingType: SigningType.PARITY_SIGNER, }, accounts: accountsToSave, + external: false, }); onComplete(); diff --git a/src/renderer/pages/Onboarding/Vault/ManageSingleshard/ManageSingleshard.tsx b/src/renderer/pages/Onboarding/Vault/ManageSingleshard/ManageSingleshard.tsx index 14acf1864c..5c3538b75c 100644 --- a/src/renderer/pages/Onboarding/Vault/ManageSingleshard/ManageSingleshard.tsx +++ b/src/renderer/pages/Onboarding/Vault/ManageSingleshard/ManageSingleshard.tsx @@ -63,6 +63,7 @@ export const ManageSingleshard = ({ seedInfo, onBack, onClose, onComplete }: Pro if (!accountId || accountId.length === 0) return; walletModel.events.singleshardCreated({ + external: false, wallet: { name: walletName, type: WalletType.SINGLE_PARITY_SIGNER, diff --git a/src/renderer/pages/Onboarding/Vault/ManageVault/model/manage-vault-model.ts b/src/renderer/pages/Onboarding/Vault/ManageVault/model/manage-vault-model.ts index a1a4ddc9ff..043700819a 100644 --- a/src/renderer/pages/Onboarding/Vault/ManageVault/model/manage-vault-model.ts +++ b/src/renderer/pages/Onboarding/Vault/ManageVault/model/manage-vault-model.ts @@ -128,6 +128,7 @@ sample({ return { wallet, accounts: [root, ...accounts], + external: false, }; }, target: walletModel.events.multishardCreated, diff --git a/src/renderer/pages/Onboarding/WalletConnect/ManageStep.tsx b/src/renderer/pages/Onboarding/WalletConnect/ManageStep.tsx index 0c119af91a..2b1c2c7fe7 100644 --- a/src/renderer/pages/Onboarding/WalletConnect/ManageStep.tsx +++ b/src/renderer/pages/Onboarding/WalletConnect/ManageStep.tsx @@ -103,6 +103,7 @@ export const ManageStep = ({ accounts, type, pairingTopic, sessionTopic, onBack, }); walletModel.events.walletConnectCreated({ + external: false, wallet: { name: walletName.trim(), type, diff --git a/src/renderer/pages/Onboarding/WatchOnly/WatchOnly.tsx b/src/renderer/pages/Onboarding/WatchOnly/WatchOnly.tsx index da9c73a802..f2cf6d928f 100644 --- a/src/renderer/pages/Onboarding/WatchOnly/WatchOnly.tsx +++ b/src/renderer/pages/Onboarding/WatchOnly/WatchOnly.tsx @@ -80,6 +80,7 @@ const WatchOnly = ({ isOpen, onClose, onComplete }: Props) => { const isEthereum = isEthereumAccountId(accountId); walletModel.events.watchOnlyCreated({ + external: false, wallet: { name: walletName, type: WalletType.WATCH_ONLY, diff --git a/src/renderer/processes/multisigs/model/__tests__/multisigs-model.test.ts b/src/renderer/processes/multisigs/model/__tests__/multisigs-model.test.ts index 252e5e5d00..aaba94fa6b 100644 --- a/src/renderer/processes/multisigs/model/__tests__/multisigs-model.test.ts +++ b/src/renderer/processes/multisigs/model/__tests__/multisigs-model.test.ts @@ -1,35 +1,11 @@ import { allSettled, fork } from 'effector'; -import { - AccountType, - ChainOptions, - ChainType, - ConnectionType, - CryptoType, - ExternalType, - SigningType, - WalletType, -} from '@/shared/core'; +import { AccountType, ChainOptions, ConnectionType } from '@/shared/core'; import { multisigService } from '@/entities/multisig'; import { networkModel } from '@/entities/network'; import { walletModel } from '@/entities/wallet'; import { multisigsModel } from '../multisigs-model'; -const signatories = [ - { - accountId: '0x01', - address: 'F7NZ', - }, - { - accountId: '0x02', - address: 'F7Pa', - }, - { - accountId: '0x03', - address: 'F7XB', - }, -]; - describe('features/multisigs/model/multisigs-model', () => { beforeEach(() => { jest.restoreAllMocks(); @@ -42,62 +18,6 @@ describe('features/multisigs/model/multisigs-model', () => { ]); }); - test('should create multisigs', async () => { - const multisigCreation = jest.spyOn(walletModel.events, 'multisigCreated'); - - const newMultisig = { - wallet: { - name: 'F7Hs', - type: WalletType.MULTISIG, - signingType: SigningType.MULTISIG, - }, - accounts: [ - { - threshold: 2, - accountId: '0x00', - signatories: signatories.map(({ accountId, address }) => ({ - accountId, - address, - })), - name: 'F7Hs', - chainId: '0x01', - cryptoType: CryptoType.SR25519, - chainType: ChainType.SUBSTRATE, - type: AccountType.MULTISIG, - }, - ], - }; - const scope = fork({ - values: new Map() - .set(walletModel._test.$allWallets, [ - { id: 1111, accounts: [{ walletId: 1111, accountId: '0x11', type: AccountType.CHAIN, chainId: '0x01' }] }, - ]) - .set(networkModel.$chains, { - '0x01': { - chainId: '0x01', - name: 'Westend', - options: [ChainOptions.MULTISIG], - externalApi: { [ExternalType.PROXY]: [{ url: 'http://mock-url' }] }, - }, - }), - }); - - await allSettled(networkModel.$connections, { - scope, - params: { - '0x01': { - id: 1, - chainId: '0x01', - connectionType: ConnectionType.AUTO_BALANCE, - customNodes: [], - }, - }, - }); - allSettled(multisigsModel.events.multisigsDiscoveryStarted, { scope }); - - expect(multisigCreation).toHaveBeenCalledWith(newMultisig); - }); - test('should not create a multisig we already have', async () => { const multisigCreation = jest.spyOn(walletModel.events, 'multisigCreated'); diff --git a/src/renderer/processes/multisigs/model/multisigs-model.ts b/src/renderer/processes/multisigs/model/multisigs-model.ts index 440fbee6bb..210a10f198 100644 --- a/src/renderer/processes/multisigs/model/multisigs-model.ts +++ b/src/renderer/processes/multisigs/model/multisigs-model.ts @@ -20,6 +20,7 @@ import { multisigUtils } from '../lib/mulitisigs-utils'; type SaveMultisigParams = { wallet: Omit, 'isActive' | 'accounts'>; accounts: Omit, 'walletId'>[]; + external: boolean; }; const MULTISIG_DISCOVERY_TIMEOUT = 30000; @@ -134,7 +135,10 @@ sample({ fn: ({ indexedMultisigs, chain }) => { return indexedMultisigs.map( ({ threshold, accountId, signatories }) => - multisigUtils.buildMultisig({ threshold, accountId, signatories, chain }) as SaveMultisigParams, + ({ + ...multisigUtils.buildMultisig({ threshold, accountId, signatories, chain }), + external: true, + }) as SaveMultisigParams, ); }, target: saveMultisigFx, diff --git a/src/renderer/widgets/CreateWallet/model/flow-model.ts b/src/renderer/widgets/CreateWallet/model/flow-model.ts index ff3f0fcc97..12dccae01b 100644 --- a/src/renderer/widgets/CreateWallet/model/flow-model.ts +++ b/src/renderer/widgets/CreateWallet/model/flow-model.ts @@ -251,6 +251,7 @@ sample({ signingType: SigningType.MULTISIG, }, accounts: [account], + external: false, }; }, target: walletModel.events.multisigCreated, @@ -265,7 +266,7 @@ sample({ sample({ clock: walletModel.events.walletCreatedDone, - filter: ({ wallet }) => wallet.type === WalletType.MULTISIG, + filter: ({ wallet, external }) => wallet.type === WalletType.MULTISIG && !external, fn: ({ wallet }) => wallet.id, // wallet selection shouldn't be here, but here we are target: [walletModel.events.selectWallet, walletProviderModel.events.completed],