diff --git a/src/renderer/features/flexible-multisig-create/components/SelectThreshold/SelectSignatoriesThreshold.tsx b/src/renderer/features/flexible-multisig-create/components/SelectThreshold/SelectSignatoriesThreshold.tsx index 44b9aac02..209e01d8e 100644 --- a/src/renderer/features/flexible-multisig-create/components/SelectThreshold/SelectSignatoriesThreshold.tsx +++ b/src/renderer/features/flexible-multisig-create/components/SelectThreshold/SelectSignatoriesThreshold.tsx @@ -3,7 +3,7 @@ import { useUnit } from 'effector-react'; import { type FormEvent, useState } from 'react'; import { useI18n } from '@/shared/i18n'; -import { Step } from '@/shared/lib/utils'; +import { Step, nonNullable } from '@/shared/lib/utils'; import { Alert, Button, InputHint, SmallTitleText } from '@/shared/ui'; import { Box, Select } from '@/shared/ui-kit'; import { walletModel } from '@/entities/wallet'; @@ -32,6 +32,7 @@ export const SelectSignatoriesThreshold = () => { const ownedSignatoriesWallets = useUnit(signatoryModel.$ownedSignatoriesWallets); const hasDuplicateSignatories = useUnit(signatoryModel.$hasDuplicateSignatories); const hasEmptySignatories = useUnit(signatoryModel.$hasEmptySignatories); + const hasEmptySignatoryName = useUnit(signatoryModel.$hasEmptySignatoryName); const hasOwnedSignatory = !!ownedSignatoriesWallets && ownedSignatoriesWallets?.length > 0; const hasEnoughSignatories = signatories.length >= MIN_THRESHOLD; @@ -43,7 +44,9 @@ export const SelectSignatoriesThreshold = () => { !multisigAlreadyExists && !hasEmptySignatories && isThresholdValid && - !hasDuplicateSignatories; + !hasEmptySignatoryName && + !hasDuplicateSignatories && + !hiddenMultisig; const onSubmit = (event: FormEvent) => { if (!hasClickedNext) { @@ -96,6 +99,14 @@ export const SelectSignatoriesThreshold = () => { > {t('createMultisigAccount.notEmptySignatory')} + + + {t('createMultisigAccount.notEmptySignatoryName')} +
@@ -142,9 +153,9 @@ export const SelectSignatoriesThreshold = () => { {t('createMultisigAccount.multisigHiddenExistText')} diff --git a/src/renderer/features/flexible-multisig-create/model/flexible-multisig-create.ts b/src/renderer/features/flexible-multisig-create/model/flexible-multisig-create.ts index 1607fd20e..1b6205d3d 100644 --- a/src/renderer/features/flexible-multisig-create/model/flexible-multisig-create.ts +++ b/src/renderer/features/flexible-multisig-create/model/flexible-multisig-create.ts @@ -39,7 +39,7 @@ import { networkModel, networkUtils } from '@/entities/network'; import { getExtrinsic, transactionBuilder } from '@/entities/transaction'; import { walletModel, walletUtils } from '@/entities/wallet'; import { signModel } from '@/features/operations/OperationSign/model/sign-model'; -import { ExtrinsicResult, submitModel, submitUtils } from '@/features/operations/OperationSubmit'; +import { submitModel, submitUtils } from '@/features/operations/OperationSubmit'; import { walletPairingModel } from '@/features/wallets'; import { confirmModel } from './confirm-model'; @@ -378,9 +378,38 @@ sample({ contacts: contactModel.$contacts, }, fn: ({ signatories, contacts }) => { + const signatoriesWithoutSigner = signatories.slice(1); + const contactMap = new Map(contacts.map((c) => [c.accountId, c])); + const updatedContacts: Contact[] = []; + + for (const { address, name } of signatoriesWithoutSigner) { + const contact = contactMap.get(toAccountId(address)); + + if (!contact) continue; + + updatedContacts.push({ + ...contact, + name, + }); + } + + return updatedContacts; + }, + target: contactModel.effects.updateContactsFx, +}); + +sample({ + clock: signModel.output.formSubmitted, + source: { + signatories: signatoryModel.$signatories, + contacts: contactModel.$contacts, + }, + fn: ({ signatories, contacts }) => { + const contactsSet = new Set(contacts.map((c) => c.accountId)); + return signatories .slice(1) - .filter((signatory) => !contacts.some((contact) => contact.accountId === toAccountId(signatory.address))) + .filter((signatory) => !contactsSet.has(toAccountId(signatory.address))) .map( ({ address, name }) => ({ @@ -450,26 +479,11 @@ sample({ sample({ clock: walletModel.events.walletCreatedDone, + filter: ({ wallet, external }) => wallet.type === WalletType.FLEXIBLE_MULTISIG && !external, + fn: ({ wallet }) => wallet.id, target: walletProviderModel.events.completed, }); -sample({ - clock: submitModel.output.formSubmitted, - source: { - step: $step, - hiddenMultisig: formModel.$hiddenMultisig, - }, - filter: ({ step, hiddenMultisig }, results) => { - const isSubmitStep = isStep(step, Step.SUBMIT); - const isNonNullable = nonNullable(hiddenMultisig); - const isSuccessResult = results[0]?.result === ExtrinsicResult.SUCCESS; - - return isSubmitStep && isNonNullable && isSuccessResult; - }, - fn: ({ hiddenMultisig }) => hiddenMultisig!.id, - target: walletModel.events.walletRemoved, -}); - sample({ clock: delay(submitModel.output.formSubmitted, 2000), source: $step, diff --git a/src/renderer/features/flexible-multisig-create/model/form-model.ts b/src/renderer/features/flexible-multisig-create/model/form-model.ts index 571b74867..cf66ba87c 100644 --- a/src/renderer/features/flexible-multisig-create/model/form-model.ts +++ b/src/renderer/features/flexible-multisig-create/model/form-model.ts @@ -1,7 +1,7 @@ -import { combine, createEvent, sample } from 'effector'; +import { combine, sample } from 'effector'; import { createForm } from 'effector-forms'; -import { type Chain, type ChainId, CryptoType, type Wallet } from '@/shared/core'; +import { type Chain, type ChainId, CryptoType } from '@/shared/core'; import { nonNullable, toAccountId } from '@/shared/lib/utils'; import { networkModel, networkUtils } from '@/entities/network'; import { accountUtils, walletModel, walletUtils } from '@/entities/wallet'; @@ -10,8 +10,6 @@ import { signatoryModel } from './signatory-model'; const DEFAULT_CHAIN: ChainId = '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'; // Polkadot -const restoreWallet = createEvent(); - type FormParams = { threshold: number; chainId: ChainId; @@ -144,11 +142,6 @@ sample({ target: $createMultisigForm.fields.threshold.reset, }); -sample({ - clock: restoreWallet, - target: walletModel.events.walletRestored, -}); - export const formModel = { $createMultisigForm, $multisigAccountId, diff --git a/src/renderer/features/flexible-multisig-create/model/signatory-model.ts b/src/renderer/features/flexible-multisig-create/model/signatory-model.ts index 29646b5ef..6a54f288f 100644 --- a/src/renderer/features/flexible-multisig-create/model/signatory-model.ts +++ b/src/renderer/features/flexible-multisig-create/model/signatory-model.ts @@ -41,15 +41,24 @@ const $hasEmptySignatories = combine($signatories, (signatories) => { return signatories.map(({ address }) => address).includes(''); }); +const $hasEmptySignatoryName = combine($signatories, (signatories) => { + return signatories.map(({ name }) => name).includes(''); +}); + const $ownedSignatoriesWallets = combine( - { wallets: walletModel.$wallets, signatories: $signatories }, - ({ wallets, signatories }) => - walletUtils.getWalletsFilteredAccounts(wallets, { + { + wallets: walletModel.$wallets, + signatories: $signatories, + }, + ({ wallets, signatories }) => { + const matchWallets = walletUtils.getWalletsFilteredAccounts(wallets, { walletFn: (w) => walletUtils.isValidSignatory(w), accountFn: (a) => signatories.some((s) => toAccountId(s.address) === a.accountId), - }) || [], -); + }); + return matchWallets || []; + }, +); const populateBalanceFx = createEffect((wallets: Wallet[]) => { for (const wallet of wallets) { balanceSubModel.events.walletToSubSet(wallet); @@ -104,6 +113,7 @@ export const signatoryModel = { $ownedSignatoriesWallets, $hasDuplicateSignatories, $hasEmptySignatories, + $hasEmptySignatoryName, events: { addSignatory, changeSignatory,