From c8278184b219a42970ecf72a2df28a40e9144ca8 Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Tue, 28 May 2024 23:54:55 +0800 Subject: [PATCH 1/2] feat: Support set start block number for multisig address --- .../src/components/AmendSUDTSend/index.tsx | 2 +- .../src/components/AmendSend/index.tsx | 2 +- .../src/components/MultisigAddress/hooks.ts | 80 +++++++++- .../src/components/MultisigAddress/index.tsx | 140 ++++++++++++++--- .../multisigAddress.module.scss | 53 +++++-- .../src/components/PageContainer/hooks.ts | 102 ++---------- .../src/components/PageContainer/index.tsx | 74 ++------- .../PageContainer/pageContainer.module.scss | 42 ----- .../SetStartBlockNumberDialog/index.tsx | 148 ++++++++++++++++++ .../setStartBlockNumberDialog.module.scss | 41 +++++ .../src/components/SpecialAssetList/index.tsx | 4 +- .../neuron-ui/src/containers/Main/index.tsx | 2 +- .../neuron-ui/src/services/remote/multisig.ts | 2 + .../src/services/remote/remoteApiWrapper.ts | 1 + .../neuron-ui/src/widgets/Button/index.tsx | 8 +- .../{NoDiskSpaceWarn.png => Attention.png} | Bin packages/neuron-ui/src/widgets/Icons/icon.tsx | 6 + .../widgets/MigrateCkbDataDialog/index.tsx | 2 +- .../src/block-sync-renderer/index.ts | 26 ++- .../sync/light-synchronizer.ts | 113 ++++++++----- .../src/block-sync-renderer/sync/queue.ts | 13 +- .../block-sync-renderer/sync/synchronizer.ts | 13 +- .../src/block-sync-renderer/task.ts | 10 +- packages/neuron-wallet/src/controllers/api.ts | 9 +- .../neuron-wallet/src/controllers/multisig.ts | 32 ++++ .../chain/entities/multisig-config.ts | 3 + ...820157100-RemoveAddressesMultisigConfig.ts | 4 +- .../1681360188494-AddTypeSyncProgress.ts | 7 +- .../1702781527414-RenameSyncProgress.ts | 19 +-- .../1716539079505-AddStartBlockNumber.ts | 14 ++ .../src/database/chain/ormconfig.ts | 2 + .../multisig-config-db-changed-subject.ts | 2 +- .../neuron-wallet/src/services/multisig.ts | 34 ++-- .../src/services/sync-progress.ts | 19 ++- .../index/createBlockSyncTask.test.ts | 1 + .../light-synchronizer.test.ts | 7 +- .../tests/block-sync-renderer/task.test.ts | 3 +- .../tests/services/multisig.test.ts | 24 +++ 38 files changed, 701 insertions(+), 363 deletions(-) create mode 100644 packages/neuron-ui/src/components/SetStartBlockNumberDialog/index.tsx create mode 100644 packages/neuron-ui/src/components/SetStartBlockNumberDialog/setStartBlockNumberDialog.module.scss rename packages/neuron-ui/src/widgets/Icons/{NoDiskSpaceWarn.png => Attention.png} (100%) create mode 100644 packages/neuron-wallet/src/database/chain/migrations/1716539079505-AddStartBlockNumber.ts diff --git a/packages/neuron-ui/src/components/AmendSUDTSend/index.tsx b/packages/neuron-ui/src/components/AmendSUDTSend/index.tsx index 5cdbc79812..66250d03b6 100644 --- a/packages/neuron-ui/src/components/AmendSUDTSend/index.tsx +++ b/packages/neuron-ui/src/components/AmendSUDTSend/index.tsx @@ -198,7 +198,7 @@ const AmendSUDTSend = () => {
-
diff --git a/packages/neuron-ui/src/components/AmendSend/index.tsx b/packages/neuron-ui/src/components/AmendSend/index.tsx index 7ba3873d1e..453eef097b 100644 --- a/packages/neuron-ui/src/components/AmendSend/index.tsx +++ b/packages/neuron-ui/src/components/AmendSend/index.tsx @@ -250,7 +250,7 @@ const AmendSend = () => { {t('send.allow-use-sent-cell')}
-
diff --git a/packages/neuron-ui/src/components/MultisigAddress/hooks.ts b/packages/neuron-ui/src/components/MultisigAddress/hooks.ts index 20853bdbca..d5a431f22c 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/hooks.ts +++ b/packages/neuron-ui/src/components/MultisigAddress/hooks.ts @@ -79,16 +79,21 @@ export const useConfigManage = ({ walletId, isMainnet }: { walletId: string; isM } }) }, [setEntities]) - const updateConfig = useCallback( + const onUpdateConfig = useCallback((values: Partial & { id: number }) => { + return updateMultisigConfig(values).then(res => { + if (isSuccessResponse(res)) { + setEntities(v => v.map(config => (res.result && config.id === res.result?.id ? res.result : config))) + } else { + throw new Error(typeof res.message === 'string' ? res.message : res.message.content!) + } + }) + }, []) + const onUpdateConfigAlias = useCallback( (id: number) => (e: React.SyntheticEvent) => { const { value } = e.target as HTMLInputElement - updateMultisigConfig({ id, alias: value || '' }).then(res => { - if (isSuccessResponse(res)) { - setEntities(v => v.map(config => (res.result && config.id === res.result?.id ? res.result : config))) - } - }) + onUpdateConfig({ id, alias: value || '' }) }, - [setEntities] + [onUpdateConfig] ) const deleteConfigById = useCallback( (id: number) => { @@ -141,7 +146,8 @@ export const useConfigManage = ({ walletId, isMainnet }: { walletId: string; isM return { saveConfig, allConfigs, - updateConfig, + onUpdateConfigAlias, + onUpdateConfig, deleteConfigById, onImportConfig, configs, @@ -365,3 +371,61 @@ export const useSubscription = ({ }, [isLightClient, getAndSaveMultisigSyncProgress]) return { multisigBanlances, multisigSyncProgress } } + +export const useCancelWithLightClient = () => { + const [isCloseWarningDialogShow, setIsCloseWarningDialogShow] = useState(false) + const onCancel = useCallback(() => { + setIsCloseWarningDialogShow(true) + }, [setIsCloseWarningDialogShow]) + const onCancelCloseMultisigDialog = useCallback(() => { + setIsCloseWarningDialogShow(false) + }, [setIsCloseWarningDialogShow]) + return { + isCloseWarningDialogShow, + onCancel, + onCancelCloseMultisigDialog, + } +} + +export const useSetStartBlockNumber = ({ + onUpdateConfig, +}: { + onUpdateConfig: (v: Partial & { id: number }) => Promise +}) => { + const [isSetStartBlockShown, setIsSetStartBlockShown] = useState(false) + const [editId, setEditId] = useState() + const [address, setAddress] = useState() + const [lastStartBlockNumber, setLastStartBlockNumber] = useState() + const onConfirm = useCallback( + (startBlockNumber: number) => { + if (editId) { + return onUpdateConfig({ + id: editId, + startBlockNumber, + }).then(() => { + setIsSetStartBlockShown(false) + }) + } + return Promise.reject(new Error('The Edit multisig config is empty')) + }, + [editId] + ) + const openDialog = useCallback>(e => { + const { id, address: editAddress, startBlockNumber } = e.currentTarget.dataset + if (id) { + setEditId(+id) + } + setAddress(editAddress) + setLastStartBlockNumber(startBlockNumber ? +startBlockNumber : undefined) + setIsSetStartBlockShown(true) + }, []) + return { + openDialog, + closeDialog: useCallback(() => setIsSetStartBlockShown(false), []), + isSetStartBlockShown, + onConfirm, + address, + lastStartBlockNumber, + onCancel: useCallback(() => setIsSetStartBlockShown(false), []), + } +} diff --git a/packages/neuron-ui/src/components/MultisigAddress/index.tsx b/packages/neuron-ui/src/components/MultisigAddress/index.tsx index 262fbe8596..f0f3f4bbf0 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/index.tsx +++ b/packages/neuron-ui/src/components/MultisigAddress/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useState } from 'react' +import React, { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useOnLocaleChange, @@ -11,24 +11,39 @@ import { useState as useGlobalState } from 'states' import MultisigAddressCreateDialog from 'components/MultisigAddressCreateDialog' import MultisigAddressInfo from 'components/MultisigAddressInfo' import SendFromMultisigDialog from 'components/SendFromMultisigDialog' -import { MultisigConfig } from 'services/remote' +import { MultisigConfig, changeMultisigSyncStatus } from 'services/remote' import ApproveMultisigTxDialog from 'components/ApproveMultisigTxDialog' import Dialog from 'widgets/Dialog' import Table from 'widgets/Table' import Tooltip from 'widgets/Tooltip' import AlertDialog from 'widgets/AlertDialog' -import { ReactComponent as AddSimple } from 'widgets/Icons/AddSimple.svg' -import { ReactComponent as Details } from 'widgets/Icons/Details.svg' -import { ReactComponent as Delete } from 'widgets/Icons/Delete.svg' -import { ReactComponent as Confirm } from 'widgets/Icons/Confirm.svg' -import { ReactComponent as Transfer } from 'widgets/Icons/Transfer.svg' -import { ReactComponent as Upload } from 'widgets/Icons/Upload.svg' -import { ReactComponent as Edit } from 'widgets/Icons/Edit.svg' -import { Download, Search } from 'widgets/Icons/icon' +import { + Download, + Search, + AddSimple, + Details, + Delete, + Confirm, + Transfer, + Upload, + Edit, + Confirming, +} from 'widgets/Icons/icon' +import AttentionCloseDialog from 'widgets/Icons/Attention.png' import { HIDE_BALANCE, NetworkType } from 'utils/const' import { onEnter } from 'utils/inputDevice' import getMultisigSignStatus from 'utils/getMultisigSignStatus' -import { useSearch, useConfigManage, useExportConfig, useActions, useSubscription } from './hooks' +import Button from 'widgets/Button' +import SetStartBlockNumberDialog from 'components/SetStartBlockNumberDialog' +import { + useSearch, + useConfigManage, + useExportConfig, + useActions, + useSubscription, + useCancelWithLightClient, + useSetStartBlockNumber, +} from './hooks' import styles from './multisigAddress.module.scss' @@ -58,7 +73,11 @@ const MultisigAddress = () => { useExitOnWalletChange() const { wallet: { id: walletId, addresses }, - chain: { networkID }, + chain: { + syncState: { bestKnownBlockNumber }, + networkID, + connectionStatus, + }, settings: { networks = [] }, } = useGlobalState() const isMainnet = isMainnetUtil(networks, networkID) @@ -67,11 +86,19 @@ const MultisigAddress = () => { [networks, networkID] ) const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false) - const { allConfigs, saveConfig, updateConfig, deleteConfigById, onImportConfig, configs, onFilterConfig } = - useConfigManage({ - walletId, - isMainnet, - }) + const { + allConfigs, + saveConfig, + onUpdateConfig, + onUpdateConfigAlias, + deleteConfigById, + onImportConfig, + configs, + onFilterConfig, + } = useConfigManage({ + walletId, + isMainnet, + }) const { multisigBanlances, multisigSyncProgress } = useSubscription({ walletId, isMainnet, @@ -141,10 +168,39 @@ const MultisigAddress = () => { }, [multisigBanlances, sendAction.sendFromMultisig]) const onBack = useGoBack() + const { + onCancel: onCancelWithLight, + isCloseWarningDialogShow, + onCancelCloseMultisigDialog, + } = useCancelWithLightClient() + const { + isSetStartBlockShown, + openDialog: openSetStartBlockNumber, + lastStartBlockNumber, + address, + onConfirm, + onCancel, + } = useSetStartBlockNumber({ onUpdateConfig }) + + useEffect(() => { + if (isLightClient) { + changeMultisigSyncStatus(true) + } + return () => { + if (isLightClient) { + changeMultisigSyncStatus(false) + } + } + }, [isLightClient]) return (
- +
@@ -221,8 +277,8 @@ const MultisigAddress = () => {