From 4712ae70b986a481b2392db4f4020f96f406c974 Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Sat, 7 May 2022 11:16:00 +0800 Subject: [PATCH 1/5] Refactor: Use blake160 replace addresse. Rename 'multi-sign' to 'multisig' --- .../src/components/MultisigAddress/hooks.ts | 69 ++++++++++--------- .../MultisigAddressCreateDialog/hooks.ts | 44 +++++++----- .../MultisigAddressCreateDialog/index.tsx | 19 +++-- .../SendFromMultisigDialog/hooks.ts | 6 +- packages/neuron-ui/src/locales/en.json | 4 +- packages/neuron-ui/src/locales/zh-tw.json | 4 +- packages/neuron-ui/src/locales/zh.json | 4 +- .../neuron-ui/src/services/remote/multisig.ts | 39 ++++++----- .../src/services/remote/remoteApiWrapper.ts | 1 - packages/neuron-ui/src/types/App/index.d.ts | 4 +- packages/neuron-ui/src/utils/index.ts | 1 + packages/neuron-ui/src/utils/multisig.ts | 38 ++++++++++ .../src/block-sync-renderer/sync/queue.ts | 5 +- packages/neuron-wallet/src/controllers/api.ts | 11 ++- .../neuron-wallet/src/controllers/multisig.ts | 62 +++-------------- .../src/database/address/meta.ts | 4 +- .../chain/entities/multisig-config.ts | 11 +-- ...820157092-RemoveAddressesMultisigConfig.ts | 16 +++++ ...820157094-RemoveAddressesMultisigConfig.ts | 23 +++++++ .../src/database/chain/ormconfig.ts | 4 +- .../src/models/multisig-config.ts | 37 ++++------ .../src/models/{multi-sign.ts => multisig.ts} | 40 +++++------ .../src/models/transaction-size.ts | 12 +--- packages/neuron-wallet/src/services/cells.ts | 5 +- .../src/services/hardware/hardware.ts | 8 +-- .../neuron-wallet/src/services/multisig.ts | 34 +++++---- .../src/services/transaction-sender.ts | 39 ++++++----- .../src/services/tx/transaction-generator.ts | 16 +++-- packages/neuron-wallet/src/utils/multisig.ts | 12 ++-- .../tests/block-sync-renderer/queue.test.ts | 4 +- .../tests/controllers/multisig.test.ts | 59 +++++++--------- .../tests/database/address/meta.test.ts | 4 +- .../tests/models/multi-sign.test.ts | 16 ++--- .../tests/services/cells.test.ts | 4 +- .../tests/services/multisig.test.ts | 17 +++-- .../services/tx/transaction-generator.test.ts | 18 ++--- .../services/tx/transaction-sender.test.ts | 51 +++----------- .../tests/utils/multisig.test.ts | 3 +- 38 files changed, 379 insertions(+), 369 deletions(-) create mode 100644 packages/neuron-ui/src/utils/multisig.ts create mode 100644 packages/neuron-wallet/src/database/chain/migrations/1651820157092-RemoveAddressesMultisigConfig.ts create mode 100644 packages/neuron-wallet/src/database/chain/migrations/1651820157094-RemoveAddressesMultisigConfig.ts rename packages/neuron-wallet/src/models/{multi-sign.ts => multisig.ts} (64%) diff --git a/packages/neuron-ui/src/components/MultisigAddress/hooks.ts b/packages/neuron-ui/src/components/MultisigAddress/hooks.ts index 46462b16e7..08bd5ba271 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/hooks.ts +++ b/packages/neuron-ui/src/components/MultisigAddress/hooks.ts @@ -1,8 +1,9 @@ -import React, { useCallback, useState, useEffect } from 'react' -import { useDialogWrapper, isSuccessResponse } from 'utils' +import React, { useCallback, useState, useEffect, useMemo } from 'react' +import { useDialogWrapper, isSuccessResponse, getMultisigAddress, DefaultLockInfo } from 'utils' import { MultisigOutputUpdate } from 'services/subjects' import { MultisigConfig, + MultisigEntity, saveMultisigConfig, getMultisigConfig, importMultisigConfig, @@ -13,6 +14,7 @@ import { loadMultisigTxJson, OfflineSignJSON, } from 'services/remote' +import { addressToScript, scriptToAddress } from '@nervosnetwork/ckb-sdk-utils' export const useSearch = (clearSelected: () => void) => { const [keywords, setKeywords] = useState('') @@ -39,76 +41,81 @@ export const useSearch = (clearSelected: () => void) => { } export const useConfigManage = ({ walletId, isMainnet }: { walletId: string; isMainnet: boolean }) => { - const [configs, setConfigs] = useState([]) + const [entities, setEntities] = useState([]) const saveConfig = useCallback( - ({ m, n, r, addresses, fullPayload }) => { + ({ m, n, r, addresses }: { m: number; n: number; r: number; addresses: string[] }) => { return saveMultisigConfig({ m, n, r, - addresses, - fullPayload, + blake160s: addresses.map(v => addressToScript(v).args), walletId, }).then(res => { if (isSuccessResponse(res)) { - if (res.result) { - setConfigs(v => [res.result!, ...v]) - } + setEntities(v => (res.result ? [res.result, ...v] : v)) } else { throw new Error(typeof res.message === 'string' ? res.message : res.message.content) } }) }, - [walletId, setConfigs] + [walletId, setEntities] ) useEffect(() => { - getMultisigConfig({ - walletId, - }).then(res => { - if (isSuccessResponse(res)) { - setConfigs(res.result) + getMultisigConfig(walletId).then(res => { + if (isSuccessResponse(res) && res.result) { + setEntities(res.result) } }) - }, [setConfigs, walletId]) + }, [setEntities, walletId, isMainnet]) const updateConfig = useCallback( (id: number) => (alias: string | undefined) => { updateMultisigConfig({ id, alias: alias || '' }).then(res => { if (isSuccessResponse(res)) { - setConfigs(v => v.map(config => (config.id === res.result?.id ? res.result : config))) + setEntities(v => v.map(config => (res.result && config.id === res.result?.id ? res.result : config))) } }) }, - [setConfigs] + [setEntities] + ) + const configs = useMemo( + () => + entities.map(entity => ({ + ...entity, + addresses: entity.blake160s.map(args => + scriptToAddress( + { + args, + codeHash: DefaultLockInfo.CodeHash, + hashType: DefaultLockInfo.HashType, + }, + isMainnet + ) + ), + fullPayload: getMultisigAddress(entity.blake160s, entity.r, entity.m, entity.n, isMainnet), + })), + [entities, isMainnet] ) - const filterConfig = useCallback((key: string) => { - setConfigs(v => - v.filter(config => { - return config.alias?.includes(key) || config.fullPayload === key - }) - ) - }, []) const deleteConfigById = useCallback( (id: number) => { - setConfigs(v => v.filter(config => config.id !== id)) + setEntities(v => v.filter(config => config.id !== id)) }, - [setConfigs] + [setEntities] ) const onImportConfig = useCallback(() => { - importMultisigConfig({ isMainnet, walletId }).then(res => { + importMultisigConfig(walletId).then(res => { if (isSuccessResponse(res) && res.result) { const { result } = res if (result) { - setConfigs(v => [...result, ...v]) + setEntities(v => [...result, ...v]) } } }) - }, [walletId, isMainnet]) + }, [walletId]) return { saveConfig, allConfigs: configs, updateConfig, deleteConfigById, - filterConfig, onImportConfig, } } diff --git a/packages/neuron-ui/src/components/MultisigAddressCreateDialog/hooks.ts b/packages/neuron-ui/src/components/MultisigAddressCreateDialog/hooks.ts index 4892c4dc2b..42bbba9525 100644 --- a/packages/neuron-ui/src/components/MultisigAddressCreateDialog/hooks.ts +++ b/packages/neuron-ui/src/components/MultisigAddressCreateDialog/hooks.ts @@ -1,7 +1,7 @@ import React, { useCallback, useMemo, useState, useEffect } from 'react' -import { createMultisigAddress } from 'services/remote' -import { isSuccessResponse, validateAddress, isSecp256k1Address } from 'utils' +import { validateAddress, isSecp256k1Address, getMultisigAddress } from 'utils' import { useTranslation } from 'react-i18next' +import { addressToScript } from '@nervosnetwork/ckb-sdk-utils' export enum Step { setMN = 0, @@ -28,15 +28,26 @@ export const useMAndN = () => { }, [setN] ) - const isError = useMemo(() => { - return !m || !n || Number(m) > Number(n) + const errorI18nKey: string | undefined = useMemo(() => { + if (!m || !n) { + return 'm-n-required' + } + const numM = Number(m) + const numN = Number(n) + if (numM > numN) { + return 'm-less-equal-n' + } + if (numM < 1 || numM > 255 || numN < 1 || numN > 255) { + return 'm-n-between-0-255' + } + return undefined }, [m, n]) return { m, n, setMBySelect, setNBySelect, - isError, + errorI18nKey, } } @@ -117,17 +128,18 @@ export const useViewMultisigAddress = ({ const [multisigAddress, changeMultisigAddress] = useState('') useEffect(() => { if (step === Step.viewMultiAddress) { - createMultisigAddress({ - r, - m, - n, - addresses, - isMainnet, - }).then(res => { - if (isSuccessResponse(res) && res.result) { - changeMultisigAddress(res.result) - } - }) + try { + const address = getMultisigAddress( + addresses.map(v => addressToScript(v).args), + r, + m, + n, + isMainnet + ) + changeMultisigAddress(address) + } catch (error) { + // ignore error. The ui ensures the correctness of the parameters + } } }, [step, changeMultisigAddress, m, n, r, addresses, isMainnet]) return multisigAddress diff --git a/packages/neuron-ui/src/components/MultisigAddressCreateDialog/index.tsx b/packages/neuron-ui/src/components/MultisigAddressCreateDialog/index.tsx index 09e3201315..53f9f5a302 100644 --- a/packages/neuron-ui/src/components/MultisigAddressCreateDialog/index.tsx +++ b/packages/neuron-ui/src/components/MultisigAddressCreateDialog/index.tsx @@ -18,11 +18,13 @@ const SetMN = ({ n, changeM, changeN, + errorI18nKey, }: { m: string n: string changeM: (v: string) => void changeN: (v: string) => void + errorI18nKey?: string }) => { const [t] = useTranslation() return ( @@ -34,9 +36,7 @@ const SetMN = ({     of     - {m && n && Number(m) > Number(n) && ( - {t('multisig-address.create-dialog.m-n.error')} - )} + {errorI18nKey && {t(`multisig-address.create-dialog.m-n.${errorI18nKey}`)}} ) } @@ -46,11 +46,11 @@ const MultisigAddressCreateDialog = ({ confirm: saveConfig, }: { closeDialog: () => void - confirm: (v: Omit) => Promise + confirm: (v: Omit) => Promise }) => { const [step, changeStep] = useState(Step.setMN) const [t] = useTranslation() - const { m, n, setMBySelect, setNBySelect, isError: mnErr } = useMAndN() + const { m, n, setMBySelect, setNBySelect, errorI18nKey: mnErr } = useMAndN() const next = useCallback(() => { changeStep(step + 1) }, [changeStep, step]) @@ -87,18 +87,17 @@ const MultisigAddressCreateDialog = ({ saveConfig({ m: Number(m), n: Number(n), - r, + r: Number(r), addresses, - fullPayload: multisigAddress, }).then(() => { closeDialog() }) - }, [m, n, r, addresses, multisigAddress, saveConfig, closeDialog]) + }, [m, n, r, addresses, saveConfig, closeDialog]) return ( <>

{t('multisig-address.create-dialog.title')}

- {step === Step.setMN && } + {step === Step.setMN && } {step === Step.setMultiAddress && ( <>

{t('multisig-address.create-dialog.multi-address-info.title', { m, n })}

@@ -126,7 +125,7 @@ const MultisigAddressCreateDialog = ({